Python 动态属性:能用一个参数搞定的,就不用两个

2022年7月26日 422点热度 0人点赞 0条评论
图片文章:Python七号
作者:somenzz


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__ 还能实现哪些神奇的事情,欢迎留言分享。


- 合作、交流、转载请添加微信 moonhmily1 -

图片

55340Python 动态属性:能用一个参数搞定的,就不用两个

这个人很懒,什么都没留下

文章评论