2017-08-08 63 views
4

對於模塊級的功能,這樣的代碼保存:爲什麼有必要將self作爲方法裝飾器的參數?

def dec(f): 
    def wrap(*args, **kwargs): 
     f(*args, **kwargs) 
    return wrap 

@dec 
def foo(arg1): 
    pass 

裝修時方法但是,突然間,你必須有一個參數趕實例。

def dec(f): 
    def wrap(self, *args, **kwargs): 
     f(self, *args, **kwargs) 
    return wrap 


class Test: 
    def __init__(self): 
     pass 

    @dec 
    def foo(self, arg1): 
     pass 

這是爲什麼? self有什麼特別的地方*args無法捕捉它?畢竟這不僅僅是另一種立場的論點? 另外,它是如何(self)傳入內部wrap函數?

對於第一種情況,它僅僅相當於foo = dec(foo)。從我學習的閉包中,在將foo作爲參數傳遞給裝飾器之前。它創建了一個包含__closure__的機箱,因此它可以保留傳遞給foo的任何參數。

爲什麼當涉及到方法時,顯然self似乎不是__closure__的一部分?

+1

滑稽,如果使用在第一實施例的裝飾(所以不需要重新定義分解(f)如方法級),那麼它沒有「自我」的呼喚,也在課堂上工作。 '@dec def foo(arg1):pass'然後將被調用爲Test.foo('bar').. – Uvar

回答

3

這是爲什麼? self有什麼特別的地方*args無法捕捉它?

這個問題是基於一個有缺陷的前提。事實上,*args可以包含self,無論是否有裝飾器。這通過以下兩個例子來說明。

沒有裝飾:

class Test(object): 

    def foo(self, *args): 
    return (self,) + args 

    def bar(*args): # for the purposes of illustration 
    return args 

t = Test() 
print(t.foo(42)) 
print(t.bar(42)) 

隨着裝飾:

def dec(f): 
    def wrap(*args, **kwargs): 
     return f(*args, **kwargs) 
    return wrap 

class Test(object): 

    @dec 
    def foo(self, arg1): 
     return (self, arg1) 

t = Test() 
print(t.foo(42)) 
0

我認爲這是最好的Python自己的創造者說:

http://neopythonic.blogspot.com/2008/10/why-explicit-self-has-to-stay.html

主要的兩點是:

有一個相當不錯的參數做出需要明確的自我'在參數列表中加強了這兩種調用方法的理論等同性。

另一種說法爲在參數列表中保持顯式「自我」是由戳的功能到它,這產生相應的方法動態地修改一個類的能力。

+3

呃......我其實是在問一個完全不同的問題,我可能需要重新說一下我的問題但它主要是關於裝飾和封閉。 – whiteredblack

相關問題