国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Python > 正文

Python中的默認(rèn)參數(shù)詳解

2020-02-23 01:37:52
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

文章的主題

不要使用可變對(duì)象作為函數(shù)的默認(rèn)參數(shù)例如 list,dict,因?yàn)閐ef是一個(gè)可執(zhí)行語(yǔ)句,只有def執(zhí)行的時(shí)候才會(huì)計(jì)算默認(rèn)默認(rèn)參數(shù)的值,所以使用默認(rèn)參數(shù)會(huì)造成函數(shù)執(zhí)行的時(shí)候一直在使用同一個(gè)對(duì)象,引起bug。

基本原理

在 Python 源碼中,我們使用def來(lái)定義函數(shù)或者方法。在其他語(yǔ)言中,類似的東西往往只是一一個(gè)語(yǔ)法聲明關(guān)鍵字,但def卻是一個(gè)可執(zhí)行的指令。Python代碼執(zhí)行的時(shí)候先會(huì)使用 compile 將其編譯成 PyCodeObject.

PyCodeObject 本質(zhì)上依然是一種靜態(tài)源代碼,只不過(guò)以字節(jié)碼方式存儲(chǔ),因?yàn)樗嫦蛱摂M機(jī)。因此 Code 關(guān)注的是如何執(zhí)行這些字節(jié)碼,比如棧空間大小,各種常量變量符號(hào)列表,以及字節(jié)碼與源碼行號(hào)的對(duì)應(yīng)關(guān)系等等。

PyFunctionObject 是運(yùn)行期產(chǎn)生的。它提供一個(gè)動(dòng)態(tài)環(huán)境,讓 PyCodeObject 與運(yùn)行環(huán)境關(guān)聯(lián)起來(lái)。同時(shí)為函數(shù)調(diào)用提供一系列的上下文屬性,諸如所在模塊、全局名字空間、參數(shù)默認(rèn)值等等。這是def語(yǔ)句執(zhí)行的時(shí)候干的活。

PyFunctionObject 讓函數(shù)面向邏輯,而不僅僅是虛擬機(jī)。PyFunctionObject 和 PyCodeObject 組合起來(lái)才是一個(gè)完整的函數(shù)。

下文翻譯了一篇文章,有一些很好的例子。但是由于水平有限,有些不會(huì)翻譯或者有些翻譯有誤,敬請(qǐng)諒解。如果有任何問(wèn)題請(qǐng)發(fā)郵件到 acmerfight圈gmail.com,感激不盡

主要參考資料 書籍:《深入Python編程》 大牛:shell 和 Topsky

Python對(duì)于函數(shù)中默認(rèn)參數(shù)的處理往往會(huì)給新手造成困擾(但是通常只有一次)。

當(dāng)你使用“可變”的對(duì)象作為函數(shù)中作為默認(rèn)參數(shù)時(shí)會(huì)往往引起問(wèn)題。因?yàn)樵谶@種情況下參數(shù)可以在不創(chuàng)建新對(duì)象的情況下進(jìn)行修改,例如 list dict。
代碼如下:
>>> def function(data=[]):
...     data.append(1)
...     return data
...
>>> function()
[1]
>>> function()
[1, 1]
>>> function()
[1, 1, 1]

像你所看到的那樣,list變得越來(lái)越長(zhǎng)。如果你仔細(xì)地查看這個(gè)list。你會(huì)發(fā)現(xiàn)list一直是同一個(gè)對(duì)象。
代碼如下:
>>> id(function())
12516768
>>> id(function())
12516768
>>> id(function())
12516768

原因很簡(jiǎn)單: 在每次函數(shù)調(diào)用的時(shí)候,函數(shù)一直再使用同一個(gè)list對(duì)象。這么使用引起的變化,非常“sticky”。

為什么會(huì)發(fā)生這種情況?

當(dāng)且僅當(dāng)默認(rèn)參數(shù)所在的“def”語(yǔ)句執(zhí)行的時(shí)候,默認(rèn)參數(shù)才會(huì)進(jìn)行計(jì)算。請(qǐng)看文檔描述

https://docs.python.org/2/reference/compound_stmts.html#function-definitions
其中有下面一段

"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. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified. This is generally not what was intended. A way around this is to use None as the default, and explicitly test for it in the body of the function,e.g.:

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 伊川县| 儋州市| 涡阳县| 平陆县| 嘉禾县| 尚志市| 黑河市| 酒泉市| 屯门区| 通许县| 湖口县| 台江县| 集安市| 贺兰县| 调兵山市| 龙海市| 武平县| 洛阳市| 江口县| 禹城市| 嘉义县| 永济市| 栾川县| 巴东县| 德惠市| 白山市| 浙江省| 措美县| 云浮市| 长岛县| 漠河县| 嘉峪关市| 卢氏县| 九龙城区| 桂平市| 郑州市| 田阳县| 关岭| 福州市| 南澳县| 镇远县|