作者shezion (= =)
看板Python
标题[问题] None在def中的变化
时间Tue Mar 31 11:54:57 2020
各位大大好
小弟超新手,看书自学遇到一个观念的问题想请大家指点:
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']了吗,为什麽还会
重置成[]?
先感谢回复的大大
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 118.163.224.55 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Python/M.1585626900.A.C5F.html
1F:推 TuCH: ex1的写法是不好的 result 应该封装在function里 03/31 11:59
2F:推 yushes920179: 楼上应该是在学closure 可以google一下 03/31 12:25
3F:推 cuteSquirrel: 可以参考官网的范例,刚好就是讲这个细节 03/31 12:27
5F:→ yushes920179: Ex2才是符合一般function的表现 因为result 作用域 03/31 12:29
6F:→ yushes920179: global 03/31 12:29
7F:→ cuteSquirrel: "The default value is evaluated only once" 03/31 12:29
8F:→ yushes920179: 不是 global 03/31 12:29
9F:→ cuteSquirrel: 参数是mutable object的时候,要留意这项特性。 03/31 12:30
10F:→ cuteSquirrel: 例如 list, dictionary 等等 03/31 12:31
12F:推 cuteSquirrel: ex2, result没有传入给定值,在if的判断後被清成[] 03/31 12:35
13F:推 pmove: 请google immutable 跟mutable 03/31 13:14
14F:→ shezion: 感谢大大的说明解释,小弟看懂了!!! 03/31 13:23
15F:推 Ryspon: 注意 mutable default argument 03/31 18:13
16F:推 froce: list、dict是传记忆体位置,所以你当参数,再对参数作操作 03/31 19:06
17F:→ froce: 当然会一直累加下去。 03/31 19:06
18F:推 bibo9901: 这跟传值 或 "immutable/mutable" 没有任何关系 04/01 10:16
19F:→ bibo9901: 原因是python的预设参数是一个「值」而不是「表达示」 04/01 10:16
20F:→ bibo9901: 打错字…「表达式」. 其实就相当於C/C++/Java的static 04/01 10:17
21F:→ bibo9901: local variable, 并不会在每次呼叫後都计算一个新值出来 04/01 10:18
22F:→ bibo9901: 这就是一个雷, 没有什麽「当然」可言 04/01 10:20
23F:→ pmove: 回楼上,immutable/mutable是Python官方文件的说法,你要用 04/01 11:10
24F:→ pmove: C/C++/Java的观念来解释,也许也是对的,但这就不是Python 04/01 11:10
25F:→ pmove: 官方的解释方法了。官方会这样子解释,我想是这样子就不用 04/01 11:12
26F:→ pmove: 解释啥是value,啥是reference 04/01 11:13
27F:推 Sunal: 推官方文件解释,而且严格说起来参数传进来也不是值而是一 04/01 13:09
28F:→ Sunal: 个物件 就算他是int也不是值,对py来说就是物件 04/01 13:09
29F:→ Ryspon: 觉得官方解释比较全面耶,或许这里刚好可以用 static loca 04/01 16:53
30F:→ Ryspon: l variable 来想,其他地方可能就还是得回归到 mutable / 04/01 16:53
31F:→ Ryspon: immutable 04/01 16:53
32F:推 bibo9901: 官方: "The default value is evaluated only once" 04/02 01:36
33F:→ bibo9901: "The default values are evaluated at the point of 04/02 01:37
34F:→ bibo9901: of function definition in the defining scope" 04/02 01:37
35F:→ bibo9901: 这就是我说的 预设值是真的一个value而不是expression 04/02 01:38
36F:→ bibo9901: 这个大缺陷才是因, immutable/mutable只是一个小技巧让 04/02 01:39
37F:→ bibo9901: 它不要这麽雷而已. 你就算用了immutable物件还是要考虑 04/02 01:40
38F:→ bibo9901: 该物件建立时有没有其他作用 04/02 01:40
39F:推 bibo9901: 避免成为码农第一步就是分清楚坑在哪 才能正确地躲坑 04/02 01:42
40F:→ bibo9901: 以immutable/mutable解释才是倒果为因, 思考狭隘. 04/02 01:50
41F:推 pmove: 回b大,你说的官方是出自: 04/02 09:29
43F:→ pmove: Important warning: The default value is evaluated only 04/02 09:30
44F:→ pmove: 下一句就是:This makes a difference when the default is 04/02 09:30
45F:→ pmove: a mutable object such as a list, dictionary, or 04/02 09:31
46F:→ pmove: instances of most classes. 04/02 09:31
47F:→ pmove: 里面就提到mutable object.你要觉得倒果为因,我也没办法 04/02 09:33
48F:推 pmove: 我自己是觉得你跟我讲The default value is evaluated only 04/02 09:53
49F:→ pmove: once" 我自己是没办法理解的,但是你告诉我哪些是mutable? 04/02 09:54
50F:→ pmove: 哪些是immutable? mutable/immutable会有哪种情形?这样我 04/02 09:54
51F:→ pmove: 比较好理解。所以才从mutable/immutable切入。 04/02 09:55
52F:推 froce: 推楼上,这根本就不是bug,动态语言常这样设计 04/06 07:44
53F:→ y3k: 以原文的逻辑 意思是result=[]其实只是把原本要在def前一行 04/06 11:11
54F:→ y3k: 宣告的result塞进def里面而已... 只是作用域有被限制在def里 04/06 11:12
55F:→ alvinlin: 不知道这有什麽好争的呢?反正特性知道了,顺着毛摸比较 04/06 16:30
56F:→ alvinlin: 不刺啊 04/06 16:30
57F:推 darama: 因为ex1传了一个mutable object(list) 04/30 17:00
59F:→ darama: -changing-list-y-also-change-list- 04/30 17:01