Python 動態(tài)屬性:能用一個參數(shù)搞定的,就不用兩個
Python 有個魔法函數(shù) __getattr__,可以在調用對象的某個屬性時自動執(zhí)行,利用這一點,我們可以實現(xiàn)非常靈活的功能。
舉個例子,計算兩個數(shù)的加減乘除,只需要傳入一個參數(shù)就可以進行計算:
文件: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__。執(zhí)行 op, num = name.split("_") 后,op = 'plus', num = 10。
最后返回的是一個 lambda 函數(shù),參數(shù)就是 val,因此 da.plus_10 相當于 lambda val: val + 10,因此 da.plus_10(13) 就是 13 + 10 = 23。
從 Python 3.7 開始,__getattr__ 不僅可以為類提供動態(tài)屬性,也可以為模塊提供動態(tài)屬性。
上面 __getattr__ 函數(shù)可以直接定義在模塊(一個 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 的動態(tài)屬性來實現(xiàn)一些酷炫的函數(shù):比如說減少函數(shù)的參數(shù)。你也可以思考一下,這個 __getattr__ 還能實現(xiàn)哪些神奇的事情,歡迎留言分享。
評論
圖片
表情
