A staticmethod
对象是一个描述符 https://docs.python.org/2/howto/descriptor.html。你所缺少的魔力是Python调用__get__
将对象作为类或实例的属性访问时的方法。
因此访问对象为C.foo
结果 Python 将其转换为C.__dict__['foo'].__get__(None, C)
, while instance_of_C.foo
变成type(instace_of_C).__dict__['foo'].__get__(instance_of_C, type(instance_of_C))
.
The staticmethod
对象是在C代码中定义 https://hg.python.org/cpython/file/2.7/Objects/funcobject.c#l748,但 Python 中的等效项是:
class staticmethod(object):
def __init__(self, callable):
self.f = callable
def __get__(self, obj, type=None):
return self.f
@property
def __func__(self):
return self.f
where self.f
是原始的包装函数。
所有这些都是必要的,因为函数本身也是描述符;它是为您提供方法对象的描述符协议(请参阅python 绑定和非绑定方法对象 https://stackoverflow.com/questions/13348031/python-bound-and-unbound-method-object更多细节)。因为他们也有一个__get__
方法,无需staticmethod
包装函数的对象,afunctionobj.__get__
call 会生成一个方法对象,并传入一个self
争论。
还有一个classmethod
,它使用第二个参数descriptor.__get__
将函数绑定到类,然后有property
对象,它将绑定直接转换为函数调用。看@property 装饰器如何工作? https://stackoverflow.com/questions/17330160/how-does-the-property-decorator-work.