入门篇《Python中 property 的实现原理及实现纯 Python 版》探究property的实现原理。如果你能理解那边的描述符是怎么使用的,那么你就能很快理解本文中的staticmethod和classmethod。函数和方法对于类中定义的方法,通过类调用与调用实例不同:classC:deff(self):passprint(C.f)#print(C().f)#<>一个的绑定方法C.f返回函数类型,另一个返回方法类型。它们之间的主要区别在于函数的参数是显式传递的,而方法的参数通常是隐式传递的,具体取决于调用者。例如,示例中的C().f将通过实例调用它来隐式传递自身数据。staticmethod的实现staticmethod的作用是让c.f和c.f都返回函数,相当于object.__getattribute__(c,"f")或者object.__getattribute__(C,"f")。运行代码如下:classC:@staticmethoddefsf():passc=C()print(C.sf)#print(c.sf)#print(C.sfisc.sf)#True也可以依赖描述符机制实现这样的方法,返回__get__中的原函数,所以它的Python实现版本极其简单:classstaticmethod(object):def__init__(self,f):自我。f=fdef__get__(self,obj,objtype=None):returnself.f这么简单的代码,已经是C实现版本对应的完整Python代码了。classmethodclassmethod的实现是让C.f和c.f都返回方法,并传递隐式参数cls,运行代码如下:classC:@classmethoddefcf(cls):passc=C()print(C.cf)#print(c.cf)#print(C.cfisc.cf)#Falseclassmethod不仅隐式传递参数,还需要新建一个每次对象。因此,它的实现需要使用闭包,并使用闭包函数作为返回值得到一个新的对象:classclassmethod(object):def__init__(self,f):self.f=fdef__get__(self,obj,klass=None):ifklassisNone:klass=type(obj)defnewfunc(*args):returnself.f(klass,*args)returnnewfunc这里的技巧是闭包通过闭包传递隐式cls绑定的空间。这个纯python实现在功能上没有问题,只有一个小瑕疵:c=C()print(C.cf)#.newfuncat0x000001EDF2527EE0>print(c.cf)#.newfuncat0x000001EDF2527EE0>print(C.cfisc.cf)#False虽然我们用闭包绑定了一个隐式参数,但是我们通过c.cf得到的还是一个函数对象。我没有找到在Python代码中创建实例的方法。综上所述,staticmethod和classmethod都使用了描述符机制。学习描述符不仅可以提供访问更多工具集的途径,还可以让你更深入地了解Python的工作原理,欣赏其设计的优雅。