簡體   English   中英

Python-入站出站參數

[英]Python - inbound outbound argument

我已經在《專家Python編程》中閱讀了有關這種極端情況的信息。 檢查此代碼:

def f(arg={}):
    arg['3'] = 4
    return arg

>>> print f()
{'3': 4}
>>> res = f()
>>> res['4'] = 'Still here'
>>> print f()
{'3': 4, '4': 'Still here'}

我還不清楚為什么最后一次調用f時(保存了它的返回值之后),而不是為arg分配空dict(因為它沒有參數地調用),而是保留了舊的引用。

該書這樣說:“如果在參數中創建對象,則如果函數返回該對象,則參數引用仍然有效”。

我了解“這就是它的工作方式”,但是為什么會這樣呢?

您的問題默認為可變參數(在這種情況下為字典):

def f(arg={}):
    arg['3'] = 4
    return arg

應該:

def f(arg=None):
    arg = arg if arg is not None else {}
    arg['3'] = 4
    return arg

產量:

>>> print f()
{'3': 4}
>>> res = f()
>>> res['4'] = 'Still here'
>>> print f()
{'3': 4}

如您所願。

這里的問題是,默認參數是在首次定義/解析函數時進行評估的,而不是在調用它們時進行評估。 這只是您需要注意的python解析器的細微差別。

為什么,請查看“最少驚訝”和可變默認參數

因為默認參數僅被評估一次,所以在評估和創建函數時(它們是函數定義的一部分,可以通過例如inspect.getargspec進行獲取)。

由於它們是函數的一部分,因此對函數的每次調用都將具有相同的默認值實例 如果它是一個不變的值,那么這不是問題,但是一旦它變得可變,它就可以成為陷阱。

給定班級定義,班級定義中也存在相同的“特征”:

class A(object):
    foo = {}

呼喚

x = A() 
y = A()
x.foo['bar'] = "baz"

...將給出y.foo ['bar']的值為“ baz”,因為x和y具有相同的 foo。 這就是為什么成員初始化應該在init而不是類主體中進行的原因。

聲明函子后,默認參數將被創建一次,因此對f()的每次調用都將獲得字典的相同實例,該實例開始為空。 這能回答問題嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM