我有一本需要其他功能參考的字典。我沒有將其設為全域,而是將字典作為引數傳遞。
def functionA(dictionary):
dictionary = {}
functionB(dictionary)
print(f"In A, after B, length: {len(dictionary)}")
def functionB(dictionary):
dictionary["A"] = "some value"
dictionary["B"] = "another value"
def main():
dictionary = {}
functionA(dictionary)
print(f"Back in main. Length: {len(dictionary)}")
if __name__ == "__main__":
""" This is executed when run from the command line """
main()
在上面的代碼中,main()初始化dictionary為空并將其傳遞給functionA(),這也(冗余地)將其設定為空并將其傳遞給functionB(),從而添加了幾個條目。
從main()回傳后functionA(),我預計dictionary將添加兩個條目functionB()。然而,它是空的。輸出是:
In A, after B, length: 2
Back in main. Length: 0
但是,如果我洗掉了多余dictionary = {}的functionA部分(即上述代碼塊的第二行),問題就消失了,我得到以下輸出:
In A, after B, length: 2
Back in main. Length: 2
我不明白為什么中的dictionary = {}陳述句functionA()會導致隨后添加的專案沒有被轉移回main(). 有什么見解嗎?我覺得這里有一些基本的東西我一無所知。
uj5u.com熱心網友回復:
關鍵是dictionary = {}不要清空原始字典。相反,它會創建一個新字典。如果我們將原始字典系結到不同的名稱,則更容易看出這一點:
def functionA(dictionary):
original = dictionary
dictionary = {}
functionB(dictionary)
print(f"In A, after B, length: {len(dictionary)}")
print(f"Original argument: {len(original)}")
In A, after B, length: 2
Original argument: 0
Back in main. Length: 0
創建main并傳遞給的原始字典functionA永遠不會被修改,因此它仍然是空的。傳遞給的dictionary內部是一個全新的物件(與 分開),它無法訪問,因為它從未被編輯過。functionAfunctionBoriginalmainreturn
如果要通過傳遞對原始字典的參考來修改原始字典,則需要確保使用 mutator 方法而不是重新系結名稱,例如:
def functionA(dictionary):
dictionary.clear()
functionB(dictionary)
print(f"In A, after B, length: {len(dictionary)}")
In A, after B, length: 2
Back in main. Length: 2
您還可以通過始終return設定您希望呼叫者接收的任何資料來避免這種型別的混淆:
def functionA(dictionary):
dictionary = {}
dictionary = functionB(dictionary)
print(f"In A, after B, length: {len(dictionary)}")
return dictionary
def functionB(dictionary):
dictionary["A"] = "some value"
dictionary["B"] = "another value"
return dictionary
def main():
dictionary = {}
dictionary = functionA(dictionary)
print(f"Back in main. Length: {len(dictionary)}")
In A, after B, length: 2
Back in main. Length: 2
uj5u.com熱心網友回復:
functionAdictionary將名稱重新分配給與引數中參考的記憶體不同的新記憶體。
您的代碼在邏輯上等同于:
def functionA(dictionary):
dictionary_a = {}
functionB(dictionary_a)
print(f"In A, after B, length: {len(dictionary_a)}")
def functionB(dictionary):
dictionary["A"] = "some value"
dictionary["B"] = "another value"
def main():
dictionary = {}
functionA(dictionary)
print(f"Back in main. Length: {len(dictionary)}")
if __name__ == "__main__":
""" This is executed when run from the command line """
main()
這應該使問題更加明顯。
您可以將dictionaryinmain()和dictionaryinfunctionA視為對同一字典的兩個單獨參考。當dictionaryinfunctionA被重新分配時,它不會影響dictionaryin的值main()。根據經驗,重新分配只會影響您放在陳述句左側的名稱。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/450534.html
