国产探花免费观看_亚洲丰满少妇自慰呻吟_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ā)表
主站蜘蛛池模板: 花莲市| 曲阜市| 同江市| 靖安县| 深泽县| 呼伦贝尔市| 色达县| 乌恰县| 荥经县| 乐亭县| 罗城| 临沭县| 静安区| 滨州市| 密山市| 温泉县| 广宁县| 乌鲁木齐县| 木兰县| 博野县| 怀柔区| 甘孜| 宁波市| 千阳县| 清涧县| 台中县| 潜山县| 广水市| 湖北省| 泸定县| 揭东县| 桐庐县| 延庆县| 清丰县| 吉林省| 普安县| 芜湖市| 太仓市| 兴山县| 突泉县| 桂东县|