[英]Change object directly in function is anti-pattern in python?
假設我們必須得到一些值並將其從 function 更改。
方式一
def change_b(obj):
obj['b'] = 4
result = {'a': 1, 'b': 2}
change_b(obj=result)
print(result)
如您所知,function change_b change_b()
直接在 function 中更改result['b']
的值。
方式二
from copy import deepcopy
def change_b(obj):
temp = deepcopy(obj)
temp['b'] = 4
return temp
result = {'a': 1, 'b': 2}
result = change_b(obj=result)
print(result)
但是方式 2將 object 復制到新的 object 並從新的 object 替換值。
所以,原來的 object 不會影響任何東西。 (而且,沒有副作用)
也許Way-2更安全,因為它不會改變原來的object。
我想知道哪一種更通用和pythonic的方式?
謝謝。
如果 API 明確表示它正在更新其輸入,則Way-1很好且可取: add_route(route_map, new_route)
。
如果 API 主要是為了做其他事情,那么Way-2可以避免意外的副作用。
方式 1 : dict.update()和list.sort()進行就地更新,因為這是它們的主要工作。
方式 2 :內置的sorted() function 從其輸入中生成一個新的排序列表,注意不要更改。 大致來說,它是這樣做的:
def sorted(iterable, *, key=None, reverse=False):
result = list(iterable) # copy the data
result.sort(key=key, reverse=reverse) # in-place sort
return result
希望澄清何時復制以及何時就地變異:-)
“顯式勝於隱式”
...
“面對模棱兩可,拒絕猜測的誘惑。”
- PEP 20
修改 function 中的參數不一定是壞事。 不好的是沒有充分理由這樣做。 如果您清楚您的 function 名稱和文檔將在 function 中修改參數,那很好。 如果 function 修改了參數而沒有任何跡象表明它正在嘗試這樣做,那就不太好了。
在這種情況下,您的Way-1更簡單、更明確。 很明顯,變量將被更改,並且通過查看代碼可以輕松確定更改的方式。
方式 2更糟糕,因為名稱change_b
意味着參數將被修改,而不是. 返回參數的修改版本而不修改原始版本是 python 中的標准設計模式,但最好明確說明。
例如,python 內置的set
數據結構有對應的方法: set.difference(other)
和set.difference_update(other)
。 在這兩種情況下,它們都做同樣的事情:計算這個集合和給定集合之間的差異。 在前一種情況下,返回結果而不修改原始集。 在后一種情況下,原始集合被修改並且不返回任何內容。 弄清楚哪個做什么是非常簡單的。
一般來說,您可能應該避免更新一個值並返回相同的值,因為這更加模棱兩可。 請注意大多數 python 方法如何做一個或另一個,但不是兩者都做(以及同時做這兩個的方法,如list.pop()
,這樣做是明智的,返回的 object 不是經過修改的 ZA8CFDE6331BD59EB2AC96F8911C4B666)。
據我了解 Python,解決此問題的最 Pythonic 方法是非常清楚正在發生的事情。 只要你這樣做,我認為這並不重要。
my_dict = {'a': 3, 'b': 4}
double_values_in_dict(my_dict)
# Some other code
這是一個人為的例子,但很清楚這里打算發生什么,即使沒有包含方法定義。 不清楚的是,如果您將double_values_in_dict
的返回值分配給一個新變量; 那時我不知道您可能對原始dict
object 做了什么,我必須開始深入研究該方法以弄清楚它是如何工作的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.