python文档中关于默认参数是这样说的:
Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that the same “pre-computed” value is used for each call.
因此,如下代码:
def function(data=[]):
print id(data), data
data.append(1)
for i in range(3):
function()
输出结果为:
4462873272 []
4462873272 [1]
4462873272 [1, 1]
一切正像文档中说的那样,data只计算一次,之后的调用返回的是已经计算出来的值(因此,id(data)没有变化,每次append均针对同一个data)。
但是我们带参数调用function时,即:
for i in range(3):
function([])
输出结果为:
4462872984 []
4462872984 []
4462872984 []
data的值是符合预期的,但是三次调用function,id(data)的值竟然也一样,这个是为什么呢?带参数传递时,每次调用都应该是新建data的吧。
PHP中文网2017-04-17 13:39:41
認真唸文件啊:https://docs.python.org/2/library/functions.html#id 。
Because:
Two objects with non-overlapping lifetimes may have the same id() value.
CPython中id的實作概念上相當於物件在記憶體中的位址。那請看這段程式碼:
id([])
# then it destory
id([])
# then its memory reused
前後是兩個不同的list對象,但既然前面一個對像用完就被銷毀掉了,那後面的一個list就可能重用相同的內存空間,所以id返回的地址就是一樣的了。
巴扎黑2017-04-17 13:39:41
雖然不明白最後到底有沒有回答到問題深處, 但如果這個答案能幫助有的同學對參數的疑惑 也是好的.
前一陣子我也是剛學python, 看到關於預設參數列表的一部分, 說一下我的理解.
當呼叫函數f() 連續三次時,
第一次 f() 會找到預設參數 data = []
而且它在記憶體中的位址是能通過 類似 'f.data' 尋址的.
接下來再次呼叫 f() 會重複以上操作, 因為沒有輸入一個新的參數, 會預設還是找到先前的data作為此次參數列表.
def f(data = []):
data.append("end")
print data
f()
執行前 data = []
執行後 預設參數變成 data =['end']
f()
重複上次操作 這裡data 可以理解為該函數的一個成員變數
另外 也可以呼叫 f.defaults 這個屬性來查看函數f當前情況的預設參數是什麼
如 定義完f後,
# 定义完f后的默认参数
print f.__defaults__
#>>([],)
# f() 执行后的默认参数
print f.__defaults__
#>>(['end'],)
所以預設參數在前後幾次 f()執行過程中是可變的.
而如果呼叫f([]) 的話 是不會對預設參數產生影響的,
print f.__defaults__
f([])
print f.__defaults__
f([])
print f.__defaults__
如果有興趣還可以試試看 對
f(data = [] ) 進行迭代 :)
可以參考這裡 覺得講的很清楚 Python 函數的參數
ringa_lee2017-04-17 13:39:41
這個問題是這樣子的...
這是算是python比較高級的內容了吧..初學者基本上都會碰到這個問題
函數的內省導致了,你的參數是函數類型的一個屬性(雖然沒辦法用.
來訪問).
這也就是意味著,你在定義函數的時候,你的參數已經成了這個函數對象的一部分了..類似於:
class cls():
A = []
a = cls()
b = cls()
a.A.append("a")
print b.A
你可以發現有剛剛的"a"
被印出來了..
函數這邊也是一樣的.定義的參數屬性是共享的
但是以上規則僅針對於可變資料型別,例如清單
因為不可變資料型別不是在目前這個記憶體區塊裡面修改的...而是指向了另外一個記憶體區塊..
兩個python特性:
動態類型的意思是:你的變數只是一個類似指標的東西.只不過他可以隨便亂指...他指向的是一個型別.這個類型可以是整數,字串,類別等等.
你的一個變數可以更換指向的類型.例如:a = 1
中a
指向的是一個整數類型.這個整數類型的值是1
(當然還有其他一些組成部分,例如還有count和類型聲明等等)
但是當你從新指向的時候,比如:a = "hello world"
,那麼發生的事情是,a
這個變數指向了一個字串類型,而之前1
這個整型發生的變化是count-1,等count為0了記憶體才被回收.
這就是傳說中的動態型
函數在python中也是型態.
例如你
def foo(a, b):
pass
那麼就是產生了一個函數型別,賦值給foo這個變數了..
而這個型別中所有東西都可以透過域運算子 .
來操作.