手动实现staticmethod和classmethod装饰器
首先,staticmethod和classmethod装饰器是通过非数据描述符实现的。用法简单,这里就不细说了。
这里主要分析一下staticmethod和classmethod是如何通过描述符实现的。
from functools import partial
class StaticMethod:
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
return self.func
class ClassMethod:
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
# 由于类方法需要传递cls作为第一个位置参数,这里使用偏函数固定cls为第一个位置参数,并返回函数
return partial(self.func, owner)
class A:
@StaticMethod # foo = StaticMethod(foo)得到一个描述符实例
def foo():
print('static method called')
@ClassMethod # bar = ClassMethod(bar)得到一个描述符实例
def bar(cls):
print('class method called')
a = A()
a.foo() # 访问描述符实例a.foo触发调用__get__方法,然后调用__get__方法的返回值
# static method called
a.bar()
# class method called
如果看过了上篇property,相比之下,这个就简单了不少。
这里用到了偏函数、装饰器以及面向对象的知识,希望你能得心应手。
参考:
https://docs.python.org/3/library/functions.html#staticmethod
https://docs.python.org/3/library/functions.html#classmethod