Tux*_*ude 58 python class-method getattr
我有一个类:
class MyClass:
Foo = 1
Bar = 2
Run Code Online (Sandbox Code Playgroud)
每当MyClass.Foo
或被MyClass.Bar
调用时,我都需要在返回值之前调用自定义方法.在Python中有可能吗?我知道如果我创建一个类的实例,我可以定义自己的__getattr__
方法.但我的scnenario涉及使用此类,而不创建任何实例.
另外,我需要__str__
在调用时str(MyClass.Foo)
调用自定义方法.Python提供这样的选项吗?
Mat*_*son 66
__getattr__()
并且__str__()
对于一个对象可以在它的类中找到,所以如果你想为一个类自定义那些东西,你需要class-of-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
# in python 3:
# class MyClass(metaclass=FooType):
# pass
print MyClass.Foo
print MyClass.Bar
print str(MyClass)
Run Code Online (Sandbox Code Playgroud)
打印:
foo!
bar!
custom str for MyClass
Run Code Online (Sandbox Code Playgroud)
不,对象不能拦截对其某个属性进行字符串化的请求.为属性返回的对象必须定义自己的__str__()
行为.
shx*_*hx2 15
(我知道这是一个老问题,但由于所有其他答案都使用元类...)
您可以使用以下简单classproperty
描述符:
class classproperty(object):
""" @classmethod+@property """
def __init__(self, f):
self.f = classmethod(f)
def __get__(self, *a):
return self.f.__get__(*a)()
Run Code Online (Sandbox Code Playgroud)
使用它像:
class MyClass(object):
@classproperty
def Foo(cls):
do_something()
return 1
@classproperty
def Bar(cls):
do_something_else()
return 2
Run Code Online (Sandbox Code Playgroud)
Ign*_*ams 10
首先,您需要创建一个元类,并__getattr__()
在其上进行定义.
class MyMetaclass(type):
def __getattr__(self, name):
return '%s result' % name
class MyClass(object):
__metaclass__ = MyMetaclass
print MyClass.Foo
Run Code Online (Sandbox Code Playgroud)
对于第二个,没有.调用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
Run Code Online (Sandbox Code Playgroud)
作品:
>>> MyClass.Foo
'foo!'
>>> MyClass.Bar
'bar!'
Run Code Online (Sandbox Code Playgroud)
(对于Python 2.x,将定义更改MyClass
为:
class MyClass(object):
__metaclass__ = FooType
Run Code Online (Sandbox Code Playgroud)
)
其他答案所说的内容str
适用于此解决方案:必须在实际返回的类型上实现.
归档时间: |
|
查看次数: |
23900 次 |
最近记录: |