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

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

深入討論P(yáng)ython函數(shù)的參數(shù)的默認(rèn)值所引發(fā)的問題的原因

2020-02-23 00:25:30
字體:
供稿:網(wǎng)友

本文將介紹使用mutable對(duì)象作為Python函數(shù)參數(shù)默認(rèn)值潛在的危害,以及其實(shí)現(xiàn)原理和設(shè)計(jì)目的
陷阱重現(xiàn)

我們就用實(shí)際的舉例來演示我們今天所要討論的主要內(nèi)容。

下面一段代碼定義了一個(gè)名為 generate_new_list_with 的函數(shù)。該函數(shù)的本意是在每次調(diào)用時(shí)都新建一個(gè)包含有給定 element 值的list。而實(shí)際運(yùn)行結(jié)果如下:
 

Python 2.7.9 (default, Dec 19 2014, 06:05:48)[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> def generate_new_list_with(my_list=[], element=None):...   my_list.append(element)...   return my_list...>>> list_1 = generate_new_list_with(element=1)>>> list_1[1]>>> list_2 = generate_new_list_with(element=2)>>> list_2[1, 2]>>>

可見代碼運(yùn)行結(jié)果并不和我們預(yù)期的一樣。list_2在函數(shù)的第二次調(diào)用時(shí)并沒有得到一個(gè)新的list并填入2,而是在第一次調(diào)用結(jié)果的基礎(chǔ)上append了一個(gè)2。為什么會(huì)發(fā)生這樣在其他編程語言中簡(jiǎn)直就是設(shè)計(jì)bug一樣的問題呢?
準(zhǔn)備知識(shí):Python變量的實(shí)質(zhì)

要了解這個(gè)問題的原因我們先需要一個(gè)準(zhǔn)備知識(shí),那就是:Python變量到底是如何實(shí)現(xiàn)的?

Python變量區(qū)別于其他編程語言的申明&賦值方式,采用的是創(chuàng)建&指向的類似于指針的方式實(shí)現(xiàn)的。即Python中的變量實(shí)際上是對(duì)值或者對(duì)象的一個(gè)指針(簡(jiǎn)單的說他們是值得一個(gè)名字)。我們來看一個(gè)例子。
 

p = 1p = p+1

對(duì)于傳統(tǒng)語言,上面這段代碼的執(zhí)行方式將會(huì)是,先在內(nèi)存中申明一個(gè)p的變量,然后將1存入變量p所在內(nèi)存。執(zhí)行加法操作的時(shí)候得到2的結(jié)果,將2這個(gè)數(shù)值再次存入到p所在內(nèi)存地址中。可見整個(gè)執(zhí)行過程中,變化的是變量p所在內(nèi)存地址上的值

面這段代碼中,Python實(shí)際上是現(xiàn)在執(zhí)行內(nèi)存中創(chuàng)建了一個(gè)1的對(duì)象,并將p指向了它。在執(zhí)行加法操作的時(shí)候,實(shí)際上通過加法操作得到了一個(gè)2的新對(duì)象,并將p指向這個(gè)新的對(duì)象。可見整個(gè)執(zhí)行過程中,變化的是p指向的內(nèi)存地址
函數(shù)參數(shù)默認(rèn)值陷阱的根本原因

一句話來解釋:Python函數(shù)的參數(shù)默認(rèn)值,是在編譯階段就綁定的。

現(xiàn)在,我們先從一段摘錄來詳細(xì)分析這個(gè)陷阱的原因。下面是一段從Python Common Gotchas中摘錄的原因解釋:

Python's default arguments are evaluated once when the function is defined, not each time the function is called (like it is in say, Ruby). This means that if you use a mutable default argument and mutate it, you will and have mutated that object for all future calls to the function as well.

可見如果參數(shù)默認(rèn)值是在函數(shù)編譯compile階段就已經(jīng)被確定。之后所有的函數(shù)調(diào)用時(shí),如果參數(shù)不顯示的給予賦值,那么所謂的參數(shù)默認(rèn)值不過是一個(gè)指向那個(gè)在compile階段就已經(jīng)存在的對(duì)象的指針。如果調(diào)用函數(shù)時(shí),沒有顯示指定傳入?yún)?shù)值得話。那么所有這種情況下的該參數(shù)都會(huì)作為編譯時(shí)創(chuàng)建的那個(gè)對(duì)象的一種別名存在。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 房山区| 保定市| 石家庄市| 临洮县| 托里县| 阳高县| 平山县| 尉犁县| 贺兰县| 麻城市| 东丰县| 南丹县| 三河市| 鹤壁市| 苗栗县| 康乐县| 扶风县| 承德市| 扶沟县| 湛江市| 蕲春县| 大石桥市| 通辽市| 泸西县| 班戈县| 雅安市| 湘潭县| 华亭县| 岑巩县| 扶沟县| 红原县| 碌曲县| 康平县| 宜城市| 岳普湖县| 大荔县| 当阳市| 玉山县| 上杭县| 中阳县| 古丈县|