python笔记 常见描述器静态方法

86 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情

0 环境

  • 编辑器:pycharm或者vscode
  • 系统版本:windows10
  • python版本:3.9.6

1 参考文档

参考文档

2 静态方法的实现

首先回顾一下,@staticmethod用在那里的,达到啥效果呢,就是加了它后,无论类或它的实例访问这个方法,结果是一样的(前提是用不到self变量)。如下代码和效果图。

class Demo:
    @staticmethod
    def static_show():
        print("静态方法")
if __name__ == '__main__':
    Demo.static_show()
    Demo().static_show()

image.png

而描述器就很合适,因为类或它的实例,都可以调用类变量。模仿上面文档的示例,和文档的区别在于,我没有加__call__,因为没有涉及到处理的东西,先去掉,也更加好理解,还有个是@Staticmethod,我直接跑它的示例,跑到的效果不对,然后改成和类名一致才可以。和之前描述器手写的区别在于,我需要先定义一个类变量,然后调用类变量触发__get__,这里是那个方法用到,我直接@类名绑定给它,然后它就可以触发get了。

class Staticmethod:
    def __init__(self, fn):
        print("__init__", fn)
        self.fn = fn

    def __get__(self, obj, objtype=None):
        return self.fn

class Demo:
    @Staticmethod
    def static_print(x):
        print("static_print")
        return x * 12
    
print(Demo.static_print(5))
print(Demo().static_print(5))

image.png

还有这里的Staticmethod里的fn就是我们的static_print,通过这个类走了一圈回来,是不是有种代理的味道。 image.png

3 总结

结合上面的代码中的static_print定义,常规不加@xxx这类的,否则是需要加上self,我想手动实现一个自定义的@xxxx,和python自带的效果类似,那怎么简单实现呢,需要借助描述器了,说白了就是在不借助self这类的方式,能让类知道你的存在,只需要@自定义描述器名,它里面的初始化需要传过来@绑定的那个方法名,__get__返回回去这个方法名,是不是就达到了我们的目的了。