我寫這個類別是為了測試:
class PassByReference: def __init__(self): self.variable = 'Original' self.change(self.variable) print(self.variable) def change(self, var): var = 'Changed'
當我嘗試建立實例時,輸出是 original
。所以python中的參數似乎是按值傳遞的。那是對的嗎?如何修改程式碼才能達到引用傳遞的效果,使得輸出為changed
?
有時人們會感到驚訝,像x = 1
這樣的程式碼(其中x
是參數名稱)不會影響呼叫者的參數,但像 x[0] = 1
這樣的程式碼卻會影響呼叫者的參數。發生這種情況是因為儘管有=
語法,但項目分配和切片分配是變異現有物件的方法,而不是重新分配變數。請參閱為什麼函數可以修改呼叫者感知到的某些參數,但不能修改其他參數?了解詳情。
另請參閱按引用傳遞與按值傳遞之間有什麼區別?用於重要的、與語言無關的術語討論。
正確答案
參數是透過賦值傳遞。這背後的理由有兩個:
- 傳入的參數實際上是物件的引用(但引用是按值傳遞的)
- 某些資料型別是可變的,但其他資料型別則不然
所以:
如果將一個可變物件傳遞給方法,則該方法將獲得對相同物件的引用,並且您可以隨心所欲地改變它,但是如果您在方法時,外部作用域對此一無所知,完成後,外部引用仍將指向原始物件。
如果將不可變物件傳遞給方法,您仍然無法重新綁定外部引用,甚至無法變更該物件。
為了更清楚地說明這一點,讓我們舉一些例子。
清單 - 可變類型
讓我們試著修改傳遞給方法的清單:
def try_to_change_list_contents(the_list): print('got', the_list) the_list.append('four') print('changed to', the_list) outer_list = ['one', 'two', 'three'] print('before, outer_list =', outer_list) try_to_change_list_contents(outer_list) print('after, outer_list =', outer_list)
輸出:
before, outer_list = ['one', 'two', 'three'] got ['one', 'two', 'three'] changed to ['one', 'two', 'three', 'four'] after, outer_list = ['one', 'two', 'three', 'four']
由於傳入的參數是對 outer_list
的引用,而不是它的副本,因此我們可以使用變異列表方法來更改它,並將更改反映在外部範圍中。
現在讓我們看看當我們嘗試更改作為參數傳入的參考時會發生什麼:
#def try_to_change_list_reference(the_list): print('got', the_list) the_list = ['and', 'we', 'can', 'not', 'lie'] print('set to', the_list) outer_list = ['we', 'like', 'proper', 'english'] print('before, outer_list =', outer_list) try_to_change_list_reference(outer_list) print('after, outer_list =', outer_list)
輸出:
before, outer_list = ['we', 'like', 'proper', 'english'] got ['we', 'like', 'proper', 'english'] set to ['and', 'we', 'can', 'not', 'lie'] after, outer_list = ['we', 'like', 'proper', 'english']
由於 the_list
參數是按值傳遞的,因此為其指派新清單不會對方法外部的程式碼產生任何影響。 the_list
是 outer_list
引用的副本,我們讓 the_list
指向一個新列表,但無法更改 outer_list
指向的位置。
字串 - 不可變型別
它是不可變的,因此我們無法更改字串的內容
#現在,讓我們嘗試更改引用
def try_to_change_string_reference(the_string): print('got', the_string) the_string = 'in a kingdom by the sea' print('set to', the_string) outer_string = 'it was many and many a year ago' print('before, outer_string =', outer_string) try_to_change_string_reference(outer_string) print('after, outer_string =', outer_string)
輸出:
before, outer_string = it was many and many a year ago got it was many and many a year ago set to in a kingdom by the sea after, outer_string = it was many and many a year ago
同樣,由於 the_string
參數是按值傳遞的,因此為其指派新字串不會對方法外部的程式碼看到任何影響。 the_string
是 outer_string
引用的副本,我們讓 the_string
指向一個新字串,但無法更改 outer_string
指向的位置。
我希望這能讓事情變得更清楚。
編輯:有人指出,這並沒有回答 @david 最初提出的問題:「我可以做些什麼來透過實際引用傳遞變數嗎?」。讓我們努力吧。
我們如何解決這個問題?
正如@andrea的回答所示,您可以傳回新值。這不會改變傳入內容的方式,但可以讓您獲得想要的資訊:
def return_a_whole_new_string(the_string): new_string = something_to_do_with_the_old_string(the_string) return new_string # then you could call it like my_string = return_a_whole_new_string(my_string)
如果您確實想避免使用返回值,您可以建立一個類別來保存您的值並將其傳遞給函數或使用現有的類,例如列表:
def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change): new_string = something_to_do_with_the_old_string(stuff_to_change[0]) stuff_to_change[0] = new_string # then you could call it like wrapper = [my_string] use_a_wrapper_to_simulate_pass_by_reference(wrapper) do_something_with(wrapper[0])
雖然這看起來有點麻煩。
以上是如何透過引用傳遞變數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。Python以简洁和强大的生态系统著称,C 则以高性能和底层控制能力闻名。

2小時內可以學會Python的基本編程概念和技能。 1.學習變量和數據類型,2.掌握控制流(條件語句和循環),3.理解函數的定義和使用,4.通過簡單示例和代碼片段快速上手Python編程。

Python在web開發、數據科學、機器學習、自動化和腳本編寫等領域有廣泛應用。 1)在web開發中,Django和Flask框架簡化了開發過程。 2)數據科學和機器學習領域,NumPy、Pandas、Scikit-learn和TensorFlow庫提供了強大支持。 3)自動化和腳本編寫方面,Python適用於自動化測試和系統管理等任務。

兩小時內可以學到Python的基礎知識。 1.學習變量和數據類型,2.掌握控制結構如if語句和循環,3.了解函數的定義和使用。這些將幫助你開始編寫簡單的Python程序。

如何在10小時內教計算機小白編程基礎?如果你只有10個小時來教計算機小白一些編程知識,你會選擇教些什麼�...

使用FiddlerEverywhere進行中間人讀取時如何避免被檢測到當你使用FiddlerEverywhere...

Python3.6環境下加載Pickle文件報錯:ModuleNotFoundError:Nomodulenamed...

如何解決jieba分詞在景區評論分析中的問題?當我們在進行景區評論分析時,往往會使用jieba分詞工具來處理文�...


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Dreamweaver CS6
視覺化網頁開發工具

WebStorm Mac版
好用的JavaScript開發工具