持续创作,加速成长!这是我参与「掘金日新计划 · 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()
而描述器就很合适,因为类或它的实例,都可以调用类变量。模仿上面文档的示例,和文档的区别在于,我没有加__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))
还有这里的Staticmethod里的fn就是我们的static_print,通过这个类走了一圈回来,是不是有种代理的味道。
3 总结
结合上面的代码中的static_print定义,常规不加@xxx这类的,否则是需要加上self,我想手动实现一个自定义的@xxxx,和python自带的效果类似,那怎么简单实现呢,需要借助描述器了,说白了就是在不借助self这类的方式,能让类知道你的存在,只需要@自定义描述器名,它里面的初始化需要传过来@绑定的那个方法名,__get__返回回去这个方法名,是不是就达到了我们的目的了。