Python 有个魔法函数 __getattr__,可以在调用对象的某个属性时自动执行,利用这一点,我们可以实现非常灵活的功能。
举个例子,计算两个数的加减乘除,只需要传入一个参数就可以进行计算:
文件:dynamic_attr_of_class.py 的内容如下:
class DynamicAttr(object): def __getattr__(self, name): op, num = name.split("_") num = int(num) return { "times": lambda val: val * num, "plus": lambda val: val + num, "minus": lambda val: val - num, "dividedby": lambda val: val / num, }[op] if __name__ == "__main__": da = DynamicAttr() assert da.plus_10(13) == 23 assert da.times_10(13) == 130 assert da.minus_10(13) == 3 assert da.dividedby_10(13) == 1.3
上面的代码,当调用 da.plus_10 的时候,就会调用到 __getattr__。执行 op, num = name.split("_") 后,op = 'plus', num = 10。
最后返回的是一个 lambda 函数,参数就是 val,因此 da.plus_10 相当于 lambda val: val + 10,因此 da.plus_10(13) 就是 13 + 10 = 23。
从 Python 3.7 开始,__getattr__ 不仅可以为类提供动态属性,也可以为模块提供动态属性。
上面 __getattr__ 函数可以直接定义在模块(一个 Python 文件)里,比如说文件 dynamic_attr_of_module.py 的内容如下:
def __getattr__(name): op, num = name.split("_") num = int(num) return { "times": lambda val: val * num, "plus": lambda val: val + num, "minus": lambda val: val - num, "dividedby": lambda val: val / num, }[op]在另一个文件 main.py 中,就可以这样来使用:
import dynamic_attr_of_module as da if __name__ == "__main__": assert da.plus_10(13) == 23 assert da.times_10(13) == 130 assert da.minus_10(13) == 3 assert da.dividedby_10(13) == 1.3是不是很方便,很灵活呢?
最后的话
本文分享了如何利用 Python 的动态属性来实现一些酷炫的函数:比如说减少函数的参数。你也可以思考一下,这个 __getattr__ 还能实现哪些神奇的事情,想要了解更多关于Python教程或者工具欢迎持续关注编程学习网
扫码二维码 获取免费视频学习资料
- 本文固定链接: http://phpxs.com/post/9801/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料
查 看2022高级编程视频教程免费获取