最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python函數(shù)的默認(rèn)參數(shù)設(shè)計(jì)示例詳解

 更新時(shí)間:2019年12月01日 08:18:04   作者:Mr-chen  
這篇文章主要給大家介紹了關(guān)于Python函數(shù)的默認(rèn)參數(shù)設(shè)計(jì)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

在Python教程里,針對(duì)默認(rèn)參數(shù),給了一個(gè)“重要警告”的例子:

def f(a, L=[]):
  L.append(a)
  return L

print(f(1))
print(f(2))
print(f(3))

默認(rèn)值只會(huì)執(zhí)行一次,也沒(méi)說(shuō)原因。會(huì)打印出結(jié)果:

[1]
[1, 2]
[1, 2, 3]

因?yàn)閷W(xué)的第一門(mén)語(yǔ)言是Ruby,所以感覺(jué)有些奇怪。 但肯定的是方法f一定儲(chǔ)存了變量L。

準(zhǔn)備知識(shí):指針

p指向不可變對(duì)象,比如數(shù)字。則相當(dāng)于p指針指向了不同的內(nèi)存地址。

p指向的是可變對(duì)象,比如list。list自身的改變,并不會(huì)改變list對(duì)象自身所在的內(nèi)存地址。所以p指向的內(nèi)存地址不變。

>>> p = 1
>>> id(p)
>>> p = p + 1
>>> id(p)
>>> p = 11
>>> id(p)

>>> p = []
>>> id(p)
>>> p.append(11)
>>> id(p)

根本原因

Python函數(shù)的參數(shù)默認(rèn)值,是在編譯階段就綁定了。(寫(xiě)代碼時(shí)就定義了。)

下面是一段從Python Common Gotchas中摘錄的原因解釋?zhuān)?/p>

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.

由此可知:

  1. 在運(yùn)行代碼時(shí),運(yùn)行到函數(shù)定義時(shí),默認(rèn)參數(shù)的表達(dá)式就被執(zhí)行了。
  2. 函數(shù)調(diào)用時(shí),不會(huì)再次運(yùn)行默認(rèn)參數(shù)的表達(dá)式。⚠️ 這點(diǎn)和Ruby完全不同。
  3. 由此可知,如果默認(rèn)參數(shù),指向一個(gè)不變對(duì)象,例如L = 1。那么在函數(shù)調(diào)用時(shí),在函數(shù)體內(nèi)對(duì)L重新賦值,L其實(shí)是一個(gè)新的指針, 指向的是一個(gè)新的內(nèi)存地址。而原來(lái)默認(rèn)參數(shù)L本身及指向的內(nèi)存地址,已經(jīng)儲(chǔ)存在最開(kāi)始編譯時(shí)的函數(shù)定義中??梢杂胈_default__查看。
  4. 如果默認(rèn)參數(shù)指向的是一個(gè)可變對(duì)象,如list, 那么L.append(a)是對(duì)可變對(duì)象自身的修改,L指向的內(nèi)存地址不變。所以每次調(diào)用函數(shù),默認(rèn)參數(shù)取出的都是這個(gè)內(nèi)存地址的對(duì)象。

第三條,修改上面的例子:

def f(a, L = 1):
  L = a
  print(id(L))
  return L

print("self",id(f.__defaults__[0]))
print(f(1))
print("self",id(f.__defaults__[0]))
print(f(33))
print("self",id(f.__defaults__[0]))

#運(yùn)行結(jié)果:
self 4353170064
1
self 4353170064
33
self 4353170064

默認(rèn)參數(shù)L,在編譯階段就綁定了,儲(chǔ)存在__default__內(nèi)。函數(shù)體內(nèi)的L = a表達(dá)式,生成的是新的變量。返回的L是新的變量,和默認(rèn)參數(shù)無(wú)關(guān)。

第四條,還是上面的例子, 改一下默認(rèn)參數(shù)的類(lèi)型為可變對(duì)象list:

def f(a, L = []):
  L.append(a)
  print(id(L))
  return L
# L = f(1)
print("self",id(f.__defaults__[0]))
print(f(1))
print("self",id(f.__defaults__[0]))
print(f(33))
print("self",id(f.__defaults__[0]))
#返回結(jié)果
self 4337586048
[1]
self 4337586048
[1, 33]
self 4337586048

由id號(hào)可知,返回的是默認(rèn)參數(shù)自身。

如何避免這個(gè)陷阱帶來(lái)不必要麻煩

def f(a, L = None):
  if L is None:
    L = []
  L.append(a)
  return L

為什么Python要這么設(shè)計(jì)

 StackOverflow 上爭(zhēng)論很多。

Ruby之所以沒(méi)有這個(gè)問(wèn)題,我想是因?yàn)镽uby的def關(guān)鍵字定義了一個(gè)封閉作用域,任何數(shù)據(jù)都必須通過(guò)參數(shù)傳入到方法內(nèi),才能用。

和Ruby比,Python參數(shù)的作用被大大消弱了。Python的出現(xiàn)晚于Ruby,其創(chuàng)始人肯定參考了Ruby的設(shè)計(jì)。拋棄了這個(gè)設(shè)計(jì),選擇了類(lèi)似javascript的函數(shù)方式。def定義的函數(shù),執(zhí)行時(shí)是可以接收外部作用域的變量的。

有觀(guān)點(diǎn)認(rèn)為:

出于Python編譯器的實(shí)現(xiàn)方式考慮,函數(shù)是一個(gè)內(nèi)部一級(jí)對(duì)象。而參數(shù)默認(rèn)值是這個(gè)對(duì)象的屬性。在其他任何語(yǔ)言中,對(duì)象屬性都是在對(duì)象創(chuàng)建時(shí)做綁定的。因此,函數(shù)參數(shù)默認(rèn)值在編譯時(shí)綁定也就不足為奇了。

本文參考了:http://cenalulu.github.io/python/default-mutable-arguments/#toc1 ,并加入了自己的理解。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Python中的請(qǐng)求重試策略深入探討

    Python中的請(qǐng)求重試策略深入探討

    在網(wǎng)絡(luò)通信中,由于各種原因,請(qǐng)求可能會(huì)失敗,為了增加程序的健壯性和可靠性,實(shí)現(xiàn)一個(gè)優(yōu)雅的請(qǐng)求重試策略是至關(guān)重要的,本文將深入探討如何在Python中實(shí)現(xiàn)優(yōu)雅的請(qǐng)求重試,通過(guò)豐富的示例代碼和詳細(xì)的解釋,幫助大家更好地理解和應(yīng)用重試機(jī)制
    2024-01-01
  • python基礎(chǔ)pandas的drop()用法示例詳解

    python基礎(chǔ)pandas的drop()用法示例詳解

    這篇文章主要介紹了python基礎(chǔ)pandas的drop()用法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • python中的scapy抓取http報(bào)文內(nèi)容

    python中的scapy抓取http報(bào)文內(nèi)容

    這篇文章主要介紹了python中的scapy抓取http報(bào)文內(nèi)容方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Windows自動(dòng)化Python?pyautogui?RPA操作實(shí)現(xiàn)

    Windows自動(dòng)化Python?pyautogui?RPA操作實(shí)現(xiàn)

    本文詳細(xì)介紹了使用Python的pyautogui庫(kù)進(jìn)行Windows自動(dòng)化操作的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-01-01
  • 結(jié)合Python的SimpleHTTPServer源碼來(lái)解析socket通信

    結(jié)合Python的SimpleHTTPServer源碼來(lái)解析socket通信

    SimpleHTTPServer是Python中一個(gè)現(xiàn)成的HTTP服務(wù)器例子,本文我們將結(jié)合Python的SimpleHTTPServer源碼來(lái)解析socket通信,我們先來(lái)看一下socket的基本概念:
    2016-06-06
  • 用Python+OpenCV對(duì)比圖像質(zhì)量的幾種方法

    用Python+OpenCV對(duì)比圖像質(zhì)量的幾種方法

    這篇文章主要介紹了用Python+OpenCV對(duì)比圖像質(zhì)量過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • django admin添加數(shù)據(jù)自動(dòng)記錄user到表中的實(shí)現(xiàn)方法

    django admin添加數(shù)據(jù)自動(dòng)記錄user到表中的實(shí)現(xiàn)方法

    下面小編就為大家分享一篇django admin添加數(shù)據(jù)自動(dòng)記錄user到表中的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • 詳解Python常用標(biāo)準(zhǔn)庫(kù)之os模塊與shutil模塊

    詳解Python常用標(biāo)準(zhǔn)庫(kù)之os模塊與shutil模塊

    os系統(tǒng)模塊與shutil文件操作模塊是Python常用的標(biāo)準(zhǔn)庫(kù),本文將通過(guò)示例詳細(xì)講解一下二者的使用,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-06-06
  • Python寫(xiě)的Tkinter程序屏幕居中方法

    Python寫(xiě)的Tkinter程序屏幕居中方法

    這篇文章主要介紹了Python寫(xiě)的Tkinter程序屏幕居中方法,Tkinter是一個(gè)python模塊,是一個(gè)調(diào)用Tcl/Tk的接口,它是一個(gè)跨平臺(tái)的腳本圖形界面接口,需要的朋友可以參考下
    2015-03-03
  • Python實(shí)戰(zhàn)之疫苗研發(fā)情況可視化

    Python實(shí)戰(zhàn)之疫苗研發(fā)情況可視化

    2020年底以來(lái),歐美,印度,中國(guó),俄羅斯等多國(guó)得制藥公司紛紛推出了針對(duì)新冠/肺炎的疫苗,這部分主要分析了2020年以來(lái)全球疫情形勢(shì),各類(lèi)疫苗在全球的地理分布,疫苗在各國(guó)的接種進(jìn)度進(jìn)行可視化展示,需要的朋友可以參考下
    2021-05-05

最新評(píng)論

清原| 天柱县| 七台河市| 北碚区| 新营市| 互助| 绿春县| 灵武市| 类乌齐县| 玉门市| 台北县| 古浪县| 永平县| 东辽县| 黄平县| 思南县| 乌苏市| 长泰县| 抚宁县| 伽师县| 南昌市| 博客| 仪陇县| 万年县| 武功县| 宝山区| 长岭县| 汉阴县| 德惠市| 宜章县| 北京市| 桃江县| 姚安县| 长治市| 邵阳市| 密云县| 英山县| 若尔盖县| 德化县| 靖远县| 偏关县|