__getattr__用于python中的静态/类variables
我有一个类像:
class MyClass: Foo = 1 Bar = 2
每当MyClass.Foo
或MyClass.Bar
被调用,我需要一个自定义的方法被调用之前返回的值。 在Python中可能吗? 我知道这是可能的,如果我创build一个类的实例,我可以定义我自己的__getattr__
方法。 但是我的scneario涉及到使用这个类而不创build任何实例。
另外我需要调用str(MyClass.Foo)
时调用自定义的__str__
方法。 Python是否提供这样的选项?
__getattr__()
和__str__()
在它的类中被find,所以如果你想为一个类自定义这些东西,你需要一个class-a-class。 元类。
class FooType(type): def _foo_func(cls): return 'foo!' def _bar_func(cls): return 'bar!' def __getattr__(cls, key): if key == 'Foo': return cls._foo_func() elif key == 'Bar': return cls._bar_func() raise AttributeError(key) def __str__(cls): return 'custom str for %s' % (cls.__name__,) class MyClass: __metaclass__ = FooType print MyClass.Foo print MyClass.Bar print str(MyClass)
打印:
foo! bar! custom str for MyClass
不,一个对象不能拦截一个对其属性进行string化的请求。 为属性返回的对象必须定义自己的__str__()
行为。
(我知道这是一个老问题,但是因为所有其他答案都使用元类…)
您可以使用以下简单的类classproperty
描述符:
class classproperty(object): """ @classmethod+@property """ def __init__(self, f): self.f = classmethod(f) def __get__(self, *a): return self.f.__get__(*a)()
像这样使用它:
class MyClass(object): @classproperty def Foo(cls): do_something() return 1 @classproperty def Bar(cls): do_something_else() return 2
首先,你需要创build一个元类,并在其上定义__getattr__()
。
class MyMetaclass(type): def __getattr__(self, name): return '%s result' % name class MyClass(object): __metaclass__ = MyMetaclass print MyClass.Foo
第二,没有。 调用str(MyClass.Foo)
调用MyClass.Foo.__str__()
,所以你需要为MyClass.Foo
返回一个合适的types。
惊讶的没有人指出这一点:
class FooType(type): @property def Foo(cls): return "foo!" @property def Bar(cls): return "bar!" class MyClass(metaclass=FooType): pass
作品:
>>> MyClass.Foo 'foo!' >>> MyClass.Bar 'bar!'
(对于Python 2.x,将MyClass
定义更改为:
class MyClass(object): __metaclass__ = FooType
)
关于str
的其他答案也适用于这个解决scheme:它必须在实际返回的types上实现。