编程学习网 > 编程语言 > Python > Python 动态属性:能用一个参数搞定的,就不用两个
2022
07-25

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

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教程或者工具欢迎持续关注编程学习



扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取