[英]Is it a natural design pattern to use closures and dynamically defined functions in Python?
[英]Can one use closures to simplify functions in Python?
想象一下,如果你想創建一個閉包函數來決定它的內部函數做什么的一些選項。 在這個例子中,我們有一個內部函數來決定一個數是否是偶數,但是生成器決定數字是否是偶數,好像有爭論一樣。
def generate_is_even(reject_zero):
def is_even(x):
return (x % 2 == 0 and x != 0) if reject_zero else x % 2 == 0
return is_even
如果is_even(x)運行數百萬次,則每次運行is_even(x)時仍會檢查reject_zero! 我的實際代碼有許多類似的“選項”來創建一個運行數百萬次的函數,並且為每個選項組合編寫函數會很不方便。 有沒有辦法防止這種低效率,或者Python的某些實現是否簡化了這一點?
你似乎在尋找像C中的宏一樣的東西。不幸的是,Python沒有被編譯(與純粹主義者的C不同),我沒有看到直接的解決方案來滿足你的需求。
您仍然可以在運行時開始設置所有參數,並根據參數值選擇此時的功能。 例如,您的函數生成器將類似於:
def generate_is_even(reject_zero):
def is_even_true(x):
return (x % 2 == 0 and x != 0)
def is_even_false(x):
return x % 2 == 0
return (is_even_true if reject_zero else is_even_false)
def setup(reject_zero, arg2, arg3):
is_even = generate_is_even(reject_zero)
這種情況的強烈反應是必須為處理這種參數的每個函數編寫一個生成器。 在你提出的情況下,這不是一個大問題,因為只有兩個版本的函數,不是很長。
你需要問問自己什么時候這樣做有用。 在您的情況下,只有一個布爾比較,這不是真正的資源消耗,但可能存在以前生成函數可能變得有價值的情況。
考慮在列表中緩存所有選項,生成的函數只迭代所選的函數
def generate_is_even(**kwargs):
options = {'reject_zero': lambda x: x != 0}
enabled = [options[o] for o in options if o in kwargs and kwargs[o]]
def is_even(x):
return all([fn(x) for fn in enabled]) and x % 2 == 0
return is_even
然后你可以使用
is_even_nozero = generate_is_even(reject_zero=True)
is_even_nozero(0) # gives False
is_even = generate_is_even()
is_even(0) # gives True
如果你需要添加選項然后將它添加到選項dict
,你可以使用new_option=True
是generate_is_even函數來啟用它
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.