簡體   English   中英

直接在 function 中更改 object 是 python 中的反模式?

[英]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可以避免意外的副作用。

Python 中的示例

方式 1dict.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM