麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 開發 > Python > 正文

Python函數的默認參數設計示例詳解

2024-09-09 19:02:50
字體:
來源:轉載
供稿:網友

在Python教程里,針對默認參數,給了一個“重要警告”的例子:

def f(a, L=[]):  L.append(a)  return Lprint(f(1))print(f(2))print(f(3))

默認值只會執行一次,也沒說原因。會打印出結果:

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

因為學的第一門語言是Ruby,所以感覺有些奇怪。 但肯定的是方法f一定儲存了變量L。

準備知識:指針

p指向不可變對象,比如數字。則相當于p指針指向了不同的內存地址。

p指向的是可變對象,比如list。list自身的改變,并不會改變list對象自身所在的內存地址。所以p指向的內存地址不變。

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

根本原因

Python函數的參數默認值,是在編譯階段就綁定了。(寫代碼時就定義了。)

下面是一段從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.

由此可知:

在運行代碼時,運行到函數定義時,默認參數的表達式就被執行了。 函數調用時,不會再次運行默認參數的表達式。⚠️ 這點和Ruby完全不同。 由此可知,如果默認參數,指向一個不變對象,例如L = 1。那么在函數調用時,在函數體內對L重新賦值,L其實是一個新的指針, 指向的是一個新的內存地址。而原來默認參數L本身及指向的內存地址,已經儲存在最開始編譯時的函數定義中。可以用__default__查看。 如果默認參數指向的是一個可變對象,如list, 那么L.append(a)是對可變對象自身的修改,L指向的內存地址不變。所以每次調用函數,默認參數取出的都是這個內存地址的對象。

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

def f(a, L = 1):  L = a  print(id(L))  return Lprint("self",id(f.__defaults__[0]))print(f(1))print("self",id(f.__defaults__[0]))print(f(33))print("self",id(f.__defaults__[0]))#運行結果:self 43531700641self 435317006433self 4353170064

默認參數L,在編譯階段就綁定了,儲存在__default__內。函數體內的L = a表達式,生成的是新的變量。返回的L是新的變量,和默認參數無關。

第四條,還是上面的例子, 改一下默認參數的類型為可變對象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]))
#返回結果self 4337586048[1]self 4337586048[1, 33]self 4337586048

由id號可知,返回的是默認參數自身。

如何避免這個陷阱帶來不必要麻煩

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

為什么Python要這么設計

 StackOverflow 上爭論很多。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 91精品视频在线看 | 中文字幕www | 国产精品一区在线观看 | 正在播放91 | 久久tv免费国产高清 | 337p日本欧洲亚洲大胆精蜜臀 | 亚洲最新色 | 成人男男视频拍拍拍在线观看 | 免费观看视频在线观看 | 亚洲91精品 | 国产黄色免费网站 | 久久免费视频7 | 日本羞羞影院 | 日本在线一区二区 | 91精品观看91久久久久久国产 | 久久免费视频3 | 日本一区免费看 | 亚洲白嫩在线观看 | 在线91视频| 羞羞视频免费网站日本动漫 | 亚洲精品v天堂中文字幕 | 国产免费人做人爱午夜视频 | 91久久精品一二三区 | 亚洲一区二区三区四区精品 | 久久6国产 | 激情亚洲一区二区三区 | 久久人人av | 欧美精品激情在线 | 国产成人av在线播放 | 国产乱一区二区三区视频 | 国产精品久久久久久久久久三级 | av在线播放电影 | 午夜影院a | 一本色道久久综合狠狠躁篇适合什么人看 | 国产激爽大片在线播放 | 成人激情综合网 | 国产精品一区视频 | 久久亚洲精品11p | av在线免费播放网站 | 91在线视频播放 | 久久久久久久久久久久99 |