没错,这与描述符协议有关。描述符是如何在Python中实现将接收器对象作为方法的第一个参数传递的方式。您可以从此处阅读有关Python属性查找的更多详细信息。下面以较低的级别显示了执行A.func = func;时发生的情况;A.func:
# A.func = func
A.__dict__['func'] = func # This just sets the attribute
# A.func
# The __getattribute__ method of a type object calls the __get__ method with
# None as the first parameter and the type as the second.
A.__dict__['func'].__get__(None, A) # The __get__ method of a function object
# returns an unbound method object if the
# first parameter is None.
a = A()
# a.func()
# The __getattribute__ method of object finds an attribute on the type object
# and calls the __get__ method of it with the instance as its first parameter.
a.__class__.__dict__['func'].__get__(a, a.__class__)
# This returns a bound method object that is actually just a proxy for
# inserting the object as the first parameter to the function call.
因此,是在类或实例上查找该函数,将其转换为方法,而不是将其分配给类属性。
classmethod
并且staticmethod
只是略有不同的描述符,类方法返回绑定到类型对象的绑定方法对象,而静态方法仅返回原始函数。