2016-03-03 45 views
-2

我不明白下面的代碼:這個「__init__」在這段代碼中做了什麼?

def __init__(self, create_context=None): 
    self._events = [] 
    self._create_context = (
     create_context 
     if create_context is not None else 
     lambda *_: nop_context 
    ) 

class nop_context(object): 
    """A nop context manager. 
    """ 
    def __enter__(self): 
     pass 

    def __exit__(self, *excinfo): 
     pass 

我知道self._create_context是發電機,但究竟會執行初始化後self._create_context持有?生成器表達式中的lambda是什麼?

+2

是不是'__init__'函數用於不同的類,還是你的東西順序錯誤? –

回答

1

self._create_context不是生成器,除非參數create_context中傳遞的值恰好是生成器。否則,括號只是包裝表達式,以便它可以跨越多行,大概是爲了提高可讀性。

所有此功能正在做,但是,應用默認值self._create_context。這是基本相同的:

class nop_context(object): 
    def __enter__(self): 
     pass 
    def __exit__(self, *excinfo): 
     pass 

def __init__(self, create_context=lambda *_: nop_context): 
    self._events = [] 
    self._create_context = create_context 

*_是簡單地允許函數接受的參數設置任意數量的一種方式。我寧願看到*args代替*_,因爲它是一個更容易識別的Python成語。

注意:當定義了__init__方法時,上面顯示的方式爲該類創建了一個單一的lambda函數。嚴格地說,函數是可變的。這意味着對函數對象的任何更改都會影響相應類的所有實例。這與使用可變默認值(如列表)相似。雖然在列表中可能會遇到問題,但修改一個函數並不常見,所以它不應該成爲問題。

+0

很清楚,謝謝 – Neal

0

它很容易說,如果你把它放在兩行:

create_context if create_context is not None 
else lambda *_: nop_context 

(注:這不是有效的語法把它就像我只是做了)

self._create_contextcreate_context如果create_context是除None以外的任何東西,但如果是None,那麼我們需要使用默認值。在這種情況下,默認值是一個以*_作爲參數的lambda函數,並返回nop_context*_起初可能有點混淆,但它與*args相同:這意味着我們可以採用任意數量的參數。我們將這些參數存儲在一個名爲_的元組中。使用_是因爲我們不打算使用這些參數。無論他們是什麼,我們將永遠返回nop_context

1

該代碼令人困惑地簡潔。我會用更明確的東西。

def __init__(self, create_context=None): 
    if create_context: 
     self._create_context = create_context 
    else: 
     self._create_context = lambda *_: nop_context 

按理說我應該兌現相同if create_context is not None:,要看是什麼create_context通常(我假設它的一些可贖回,可後來被稱爲懶洋洋地創建上下文)。