假设有:
class A(B):
...
其中 B
可以是 object
而 ...
是不是:
@classmethod # or @staticmethod
def c(cls): print 'Hello from c!'
我该怎么做才能调用 A.c()
不会触发 AttributeError
?
换句话说,我知道可以在运行时手动将类方法添加到类中。但是是否可以自动执行此操作,比如每次缺少类方法时都会创建一些虚拟方法?
换句话说,只有当我可以用处理 __getitem__
的字典替换 A.__dict__
时 - 但 A.__dict__
似乎不可写...
最佳答案
您可以使用 __getattr__
hook 来实现此目的在 metaclass 上.
class DefaultClassMethods(type):
def __getattr__(cls, attr):
def _defaultClassMethod(cls):
print 'Hi, I am the default class method!'
setattr(cls, attr, classmethod(_defaultClassMethod))
return getattr(cls, attr)
演示:
>>> class DefaultClassMethods(type):
... def __getattr__(cls, attr):
... def _defaultClassMethod(cls):
... print 'Hi, I am the default class method!'
... setattr(cls, attr, classmethod(_defaultClassMethod))
... return getattr(cls, attr)
...
>>> class A(object):
... __metaclass__ = DefaultClassMethods
...
>>> A.spam
<bound method DefaultClassMethods._defaultClassMethod of <class '__main__.A'>>
>>> A.spam()
Hi, I am the default class method!
请注意,我们将 classmethod
调用的结果直接设置到类中,有效地缓存它以供将来查找。
如果您需要在每次调用时重新生成类方法,请使用相同的 method to bind a function to an instance但是用类和元类代替(使用 cls.__metaclass__
与元类子类化一致):
from types import MethodType
class DefaultClassMethods(type):
def __getattr__(cls, attr):
def _defaultClassMethod(cls):
print 'Hi, I am the default class method!'
return _defaultClassMethod.__get__(cls, cls.__metaclass__)
对于静态方法,在所有情况下都直接返回函数,无需使用 staticmethod
装饰器或描述符协议(protocol)。
关于Python动态类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11281698/