[问题] 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