手动实现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

posted @ 2019-01-05 12:41  KeithTt  阅读(486)  评论(0编辑  收藏  举报