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 动态属性:能用一个参数搞定的,就不用两个

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/39669.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!