我對具有默認參數的功能有一些疑問。
具有默認參數的功能問題
import sys
from random import randint
my_list = [1,2,3]
def Veli(a, b = my_list):
my_list.append(randint(1,1500))
print a + b[-1]
print "Number of Refs:", sys.getrefcount(my_list)
print "Def args:", Veli.func_defaults
Veli(1) # This is 4
Veli(1) # We almost always obtain different result because of randint
Veli(1) # Again different results.
print Veli.func_defaults
print "Number of Refs:", sys.getrefcount(my_list)
Veli(1)
my_list = [-5] # old my_list has different address
print "Number of Refs:", sys.getrefcount(my_list) # Less than previous
print "Def args:", Veli.func_defaults
Veli(1) # Now gives same results.
print "Def args:", Veli.func_defaults
Veli(1) # Same result again...
輸出:(一些數字取決於哪些值randint返回當然。)
編號參考文獻的:3個
防守ARGS:([1, 2,3]])
([1,2,3,321,1118,739],)
編號參考文獻的:3
參考文獻號:2
防守ARGS:([1,2,3,321,1118 ,739,302],)
防守ARGS:([1,2,3,321,1118,739,302],)
下面的代碼給出了一個比前一個小的數字,因爲b和my_list不再被引用到相同的地址。
print "#ref:", sys.getrefcount(my_list) # Less than previous
現在,我們有辦法達到B,該函數的默認參數(的唯一途徑?):
Veli.func_defaults[0]
對不起我的長篇解釋。這裏是我的問題:
這是問題嗎?我的模塊字典粉碎my_list變量,然後現在my_list變量的默認地址比以前。然後,使用名爲my_list的全局變量的函數正在改變(增長),而我的默認參數不是。當
a + b[-1]
表達式被執行時,爲什麼b
看不到全局變量my_list
?我知道,b
與my_list有不同的地址(因爲mutual objects (like list) are guaranteed to refer to different, unique, newly created list),但是爲什麼Python實現,因此b
在b是函數參數時看不到全局變量?你能全面解釋一下嗎?有什麼辦法可以得到與Veli.func_defaults [0]相同的結果嗎?這段代碼執行然後說,我想改變我的名爲Veli的函數的默認參數。我不能用my_list來做這件事,因爲my_list和b有不同的地址。一種方法是更改列表中的元素Veli.func_defaults [0]。有什麼不同的方法嗎?
(它與上面的代碼沒有太大關係)如何獲取變量的地址?例如,如何獲取地址
b
?我使用內置函數,如__hash__
,但應該有更合適的方法。
注:
一)該代碼可能是無用的任何原因,但我想學的觀點。
b)中的Python 2.6.6(r266:84292,2010年9月15日,15時52分39秒)
[4.4.5 GCC]上linux2上
http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default -argument – ncoghlan 2011-02-04 14:46:24
@ncoghlan:Upvoted,因爲它是重要的演講,但由於OP利用這種行爲,在這裏不完全相關。 – delnan 2011-02-04 14:52:52