亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Python:在函數內向可變對象添加屬性

Python:在函數內向可變對象添加屬性

九州編程 2022-08-16 18:43:11
我試圖了解在這種情況下的最佳實踐是什么。假設我們有一個字典(或一個列表或其他可變的),它在函數內部被更改(但在函數外部定義)d = {'a': 0}def my_fun(x):    for i, el in enumerate(x):        d[el] = i + 1打電話,然后打印,這很好。但是,也可以通過向函數添加 return 語句來完成相同的操作(盡管不是必需的)?;蛘撸踔?,return 語句加上函數中表示 dict 的第二個 arg:my_fun(['b', 'c'])print(d){'a':0, 'b':1, 'c':2}d = {'a': 0}def my_fun(x, d):    for i, el in enumerate(x):        d[el] = i + 1    return dreturn 語句和第二個參數在這里都是多余的,我只是發現它們在清晰度方面有所幫助。它更容易閱讀。呼叫,然后再次打印d = my_fun(['b', 'c'], d)print(d){'a':0, 'b':1, 'c':2}最后,你可以選擇傳遞可變對象的副本:這可能更pythonic,但我不知道例如,在內存管理方面,制作副本是否是很好的做法。d = my_fun(['b', 'c'], d.copy())這里什么是最佳實踐?您如何處理這些類型并向函數內的可變對象添加屬性?
查看完整描述

2 回答

?
大話西游666

TA貢獻1817條經驗 獲得超14個贊

在函數中修改這樣的可變組件不是很好的做法。你是對的,你建議的兩種方法都修改了原始對象。對于像這樣的簡單情況,最好返回一個新對象。


在這個簡單的例子中,正如你所說,你可以復制字典。IMO你應該在函數中執行此操作。您需要從一開始就清楚字典的結構是什么,因為您可能需要一個深度副本。


def my_fun(x, d):

    d = d.copy()

    for i, el in enumerate(x):

        d[el] = i + 1

    return d

或者,您可以創建一個新詞典并使用舊詞典進行更新。我更喜歡這個,但你必須小心重復鍵。


def my_func(x, d):

    result = {el: i for i, el in enumerate(x)}

    result.update(d)

    return result

對于更復雜的事情,您可能有一個類來封裝整個事情。


class Foo:

    def __init__(self, d):

        self.d = d


    def update(self, x):

        for i, el in enumerate(x):

            self.d[el] = i


查看完整回答
反對 回復 2022-08-16
?
郎朗坤

TA貢獻1921條經驗 獲得超9個贊

您的兩個示例并不等效。它們之所以以這種方式顯示,只是因為您碰巧將函數參數命名為與全局變量相同的名稱。等效函數是:


d = {'a': 0}


def my_fun(x, foo):

    for i, el in enumerate(foo):

        foo[el] = i + 1

    return foo

但這個函數不是“pythonic”。修改傳入的對象是可以的,但是當您這樣做時,也不要返回它。如果在函數中復制對象,則返回它。你所做的只是制造了一個模棱兩可的東西 - 在一個眩光點上,我會從返回聲明中假設原始的字典沒有被修改。至于清晰度,這就是文檔字符串的用途?,F在每個打字的人都知道發生了什么。help(my_fun)


def my_fun(x, foo):

    """Update foo with an enumeration of x"""

    for i, el in enumerate(foo):

        foo[el] = i + 1

您的第一個示例是最危險的。它對全局對象執行靜默更新。我們盡量避免這種事情。當它完成時,doc字符串和希望函數本身的名稱清楚地表明一些令人討厭的panky正在進行中。


至于復制,這是你可以讓調用者決定的事情。更新傳遞到函數中的字典比復制它更通用,因為調用方可以決定是否應復制正在更新的數據。當然,由于您不再返回更新的對象,因此調用方需要做更多的工作。


d_copy = d.copy()

my_fun(['b', 'c'], d_copy)

這還不錯。代碼很清楚。這并不是說我們用完了換行符或其他東西。


查看完整回答
反對 回復 2022-08-16
  • 2 回答
  • 0 關注
  • 142 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號