[問題] None在def中的變化

作者: shezion (= =)   2020-03-31 11:54:57
各位大大好
小弟超新手,看書自學遇到一個觀念的問題想請大家指點:
ex1:
>>>def buggy(arg,result=[]):
result.append(arg)
print(result)
>>>buggy('a')
["a"]
>>>buggy('b')
["a","b"]
ex1中,buggy()輸出的值會一直累加下去
ex2:
>>>def non(arg,result=None):
if result is None:
result =[]
result.append(arg)
print(result)
>>>non('a')
['a']
>>>non('b')
['b']
ex2中,non()輸出的值都只輸出該次的值,不會留下上一次輸入過的值
根據書中說明預設的引數值只在定義時被計算,想請問為什麼ex2裡
引述預設值改為None時,不會發生印出的內容包含前一次呼叫內容,
第一次輸出['a']後,result不是已經變成['a']了嗎,為什麼還會
重置成[]?
先感謝回復的大大
作者: TuCH (謬客)   2020-03-31 11:59:00
ex1的寫法是不好的 result 應該封裝在function裡
作者: yushes920179 (樂冰)   2020-03-31 12:25:00
樓上應該是在學closure 可以google一下
作者: cuteSquirrel (松鼠)   2020-03-31 12:27:00
可以參考官網的範例,剛好就是講這個細節https://imgur.com/a/1fBIXKJ
作者: yushes920179 (樂冰)   2020-03-31 12:29:00
Ex2才是符合一般function的表現 因為result 作用域global
作者: cuteSquirrel (松鼠)   2020-03-31 12:29:00
"The default value is evaluated only once"
作者: cuteSquirrel (松鼠)   2020-03-31 12:30:00
參數是mutable object的時候,要留意這項特性。例如 list, dictionary 等等官網說明: https://bit.ly/3dIKVy0ex2, result沒有傳入給定值,在if的判斷後被清成[]
作者: pmove (金疾檸檬)   2020-03-31 13:14:00
請google immutable 跟mutable
作者: shezion (= =)   2020-03-31 13:23:00
感謝大大的說明解釋,小弟看懂了!!!
作者: Ryspon (Ry)   2020-03-31 18:13:00
注意 mutable default argument
作者: froce (froce)   2020-03-31 19:06:00
list、dict是傳記憶體位置,所以你當參數,再對參數作操作當然會一直累加下去。
作者: bibo9901 (function(){})()   2020-04-01 10:16:00
這跟傳值 或 "immutable/mutable" 沒有任何關係原因是python的預設參數是一個「值」而不是「表達示」打錯字…「表達式」. 其實就相當於C/C++/Java的staticlocal variable, 並不會在每次呼叫後都計算一個新值出來這就是一個雷, 沒有什麼「當然」可言
作者: pmove (金疾檸檬)   2020-04-01 11:10:00
回樓上,immutable/mutable是Python官方文件的說法,你要用C/C++/Java的觀念來解釋,也許也是對的,但這就不是Python官方的解釋方法了。官方會這樣子解釋,我想是這樣子就不用解釋啥是value,啥是reference
作者: Sunal (SSSSSSSSSSSSSSSSSSSSSSS)   2020-04-01 13:09:00
推官方文件解釋,而且嚴格說起來參數傳進來也不是值而是一個物件 就算他是int也不是值,對py來說就是物件
作者: Ryspon (Ry)   2020-04-01 16:53:00
覺得官方解釋比較全面耶,或許這裡剛好可以用 static local variable 來想,其他地方可能就還是得回歸到 mutable /immutable
作者: bibo9901 (function(){})()   2020-04-02 01:36:00
官方: "The default value is evaluated only once""The default values are evaluated at the point ofof function definition in the defining scope"這就是我說的 預設值是真的一個value而不是expression這個大缺陷才是因, immutable/mutable只是一個小技巧讓它不要這麼雷而已. 你就算用了immutable物件還是要考慮該物件建立時有沒有其他作用避免成為碼農第一步就是分清楚坑在哪 才能正確地躲坑以immutable/mutable解釋才是倒果為因, 思考狹隘.
作者: pmove (金疾檸檬)   2020-04-02 09:29:00
回b大,你說的官方是出自:https://docs.python.org/3.3/tutorial/controlflow.htmlImportant warning: The default value is evaluated only下一句就是:This makes a difference when the default isa mutable object such as a list, dictionary, orinstances of most classes.裡面就提到mutable object.你要覺得倒果為因,我也沒辦法我自己是覺得你跟我講The default value is evaluated onlyonce" 我自己是沒辦法理解的,但是你告訴我哪些是mutable?哪些是immutable? mutable/immutable會有哪種情形?這樣我比較好理解。所以才從mutable/immutable切入。
作者: froce (froce)   2020-04-06 07:44:00
推樓上,這根本就不是bug,動態語言常這樣設計
作者: y3k (激流を制するは静水)   2020-04-06 11:11:00
以原文的邏輯 意思是result=[]其實只是把原本要在def前一行宣告的result塞進def裡面而已... 只是作用域有被限制在def裡
作者: alvinlin (林矜業)   2020-04-06 16:30:00
不知道這有什麼好爭的呢?反正特性知道了,順著毛摸比較不刺啊
作者: TuCH (謬客)   2020-03-31 19:59:00
ex1的寫法是不好的 result 應該封裝在function裡
作者: yushes920179 (樂冰)   2020-03-31 20:25:00
樓上應該是在學closure 可以google一下
作者: cuteSquirrel (松鼠)   2020-03-31 20:27:00
可以參考官網的範例,剛好就是講這個細節https://imgur.com/a/1fBIXKJ
作者: yushes920179 (樂冰)   2020-03-31 20:29:00
Ex2才是符合一般function的表現 因為result 作用域global
作者: cuteSquirrel (松鼠)   2020-03-31 20:29:00
"The default value is evaluated only once"
作者: cuteSquirrel (松鼠)   2020-03-31 20:30:00
參數是mutable object的時候,要留意這項特性。例如 list, dictionary 等等官網說明: https://bit.ly/3dIKVy0ex2, result沒有傳入給定值,在if的判斷後被清成[]
作者: pmove (金疾檸檬)   2020-03-31 21:14:00
請google immutable 跟mutable
作者: shezion (= =)   2020-03-31 21:23:00
感謝大大的說明解釋,小弟看懂了!!!
作者: Ryspon (Ry)   2020-04-01 02:13:00
注意 mutable default argument
作者: froce (froce)   2020-04-01 03:06:00
list、dict是傳記憶體位置,所以你當參數,再對參數作操作當然會一直累加下去。
作者: bibo9901 (function(){})()   2020-04-01 18:16:00
這跟傳值 或 "immutable/mutable" 沒有任何關係原因是python的預設參數是一個「值」而不是「表達示」打錯字…「表達式」. 其實就相當於C/C++/Java的staticlocal variable, 並不會在每次呼叫後都計算一個新值出來這就是一個雷, 沒有什麼「當然」可言
作者: pmove (金疾檸檬)   2020-04-01 19:10:00
回樓上,immutable/mutable是Python官方文件的說法,你要用C/C++/Java的觀念來解釋,也許也是對的,但這就不是Python官方的解釋方法了。官方會這樣子解釋,我想是這樣子就不用解釋啥是value,啥是reference
作者: Sunal (SSSSSSSSSSSSSSSSSSSSSSS)   2020-04-01 21:09:00
推官方文件解釋,而且嚴格說起來參數傳進來也不是值而是一個物件 就算他是int也不是值,對py來說就是物件
作者: Ryspon (Ry)   2020-04-02 00:53:00
覺得官方解釋比較全面耶,或許這裡剛好可以用 static local variable 來想,其他地方可能就還是得回歸到 mutable /immutable
作者: bibo9901 (function(){})()   2020-04-02 09:36:00
官方: "The default value is evaluated only once""The default values are evaluated at the point ofof function definition in the defining scope"這就是我說的 預設值是真的一個value而不是expression這個大缺陷才是因, immutable/mutable只是一個小技巧讓它不要這麼雷而已. 你就算用了immutable物件還是要考慮該物件建立時有沒有其他作用避免成為碼農第一步就是分清楚坑在哪 才能正確地躲坑以immutable/mutable解釋才是倒果為因, 思考狹隘.
作者: pmove (金疾檸檬)   2020-04-02 17:29:00
回b大,你說的官方是出自:https://docs.python.org/3.3/tutorial/controlflow.htmlImportant warning: The default value is evaluated only下一句就是:This makes a difference when the default isa mutable object such as a list, dictionary, orinstances of most classes.裡面就提到mutable object.你要覺得倒果為因,我也沒辦法我自己是覺得你跟我講The default value is evaluated onlyonce" 我自己是沒辦法理解的,但是你告訴我哪些是mutable?哪些是immutable? mutable/immutable會有哪種情形?這樣我比較好理解。所以才從mutable/immutable切入。
作者: froce (froce)   2020-04-06 15:44:00
推樓上,這根本就不是bug,動態語言常這樣設計
作者: y3k (激流を制するは静水)   2020-04-06 19:11:00
以原文的邏輯 意思是result=[]其實只是把原本要在def前一行宣告的result塞進def裡面而已... 只是作用域有被限制在def裡
作者: alvinlin (林矜業)   2020-04-07 00:30:00
不知道這有什麼好爭的呢?反正特性知道了,順著毛摸比較不刺啊
作者: darama (DoRaMa)   2020-04-30 17:00:00
因為ex1傳了一個mutable object(list)https://docs.python.org/3/faq/programming.html#why-did-changing-list-y-also-change-list-

Links booklink

Contact Us: admin [ a t ] ucptt.com