我有一个类:
class MyClass:
Foo = 1
Bar = 2
每当调用 MyClass.Foo
或 MyClass.Bar
时,我需要在返回值之前调用自定义方法。在 Python 中有可能吗?我知道如果我创建一个类的实例并且我可以定义我自己的方法是可能的。但是我的场景涉及使用此类而不创建它的任何实例。
我还需要一个自定义 __getattr__
方法,以便在调用 __str__
时调用。 Python 是否提供这样的选项?
str(MyClass.Foo)
和 __getattr__()
可以在它的类中找到,所以如果你想为一个类定制这些东西,你需要类中的类。一个元类。
__str__()
印刷:
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
# # in python 3:
# class MyClass(metaclass=FooType):
# pass
print(MyClass.Foo)
print(MyClass.Bar)
print(str(MyClass))
不,对象不能拦截对其属性之一进行字符串化的请求。为属性返回的对象必须定义自己的 foo!
bar!
custom str for MyClass
行为。
(我知道这是一个老问题,但由于所有其他答案都使用元类...)
您可以使用以下简单的__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
。
__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
作品:
class FooType(type):
@property
def Foo(cls):
return "foo!"
@property
def Bar(cls):
return "bar!"
class MyClass(metaclass=FooType):
pass
(对于 Python 2.x,将 >>> MyClass.Foo
'foo!'
>>> MyClass.Bar
'bar!'
的定义更改为:
MyClass
)
其他答案所说的 class MyClass(object):
__metaclass__ = FooType
对这个解决方案适用:它必须在实际返回的类型上实现。
根据情况我使用这个模式
str
然后导入并使用它。
class _TheRealClass:
def __getattr__(self, attr):
pass
LooksLikeAClass = _TheRealClass()
这避免了元类的使用,并处理了一些用例。