2013-10-15 41 views
0

我正在編寫一個方法裝飾器並需要訪問定義當前裝飾方法的類。獲取包含類的方法

問題似乎是這樣的,用Python 3中的方法只是函數,除非類被實例化。

有沒有辦法解決這個問題?我真的不想要擺弄__qualname__ ...

In [29]: class A: 
    ....:  def B(self): 
    ....:   pass 
    ....:  

In [30]: A.B.__qualname__ 
Out[30]: 'A.B' 

# This is what I want: 
>>> get_class(A.B) 
A 
+2

爲什麼不創建類裝飾器呢?在課堂中裝飾功能時,*課程尚未創建*。 –

+0

@MartijnPieters,因爲裝飾器相對於包含類*更改裝飾方法*的語義。 '@decorate(「some_method」)\ nclass Foo:...'似乎非常直觀。如果沒有其他選擇,我會創建一個自定義的基類或元類,並檢查其中所有方法的屬性。或類似的東西。 – dom0

+0

@ Michael0x2a:不,這不是一個正確的副本。方法上的函數裝飾器無法確定類* yet *,因爲在定義了所有函數之前沒有類對象。 –

回答

1

你不能,因爲當時你對的方法裝飾運行,類是尚未創建

一個例子說明了這好一點:

class Foo: 
    @spam 
    def bar(self): pass 

spam(bar)調用產生的裝飾功能,我們是Python的運行來定義類主體僞函數內。只有當僞函數完成執行時,該函數的局部名稱空間纔會變成類體,並創建實際的類對象本身。

這意味着在運行spam()時還沒有Foo類對象。

相反,創建一個類裝飾:

@spam 
class Foo: 
    def bar(self): pass 

現在spam()傳遞全,完整Foo類讓您獲得的類和方法兩者。

如果您需要標記的類裝修的具體方法,你可以使用一個標誌裝飾,設置的功能屬性:

def marker(func): 
    func._marked = True 
    return func 

使用此裝飾在類體內的方法,你想裝飾,然後使用類裝飾器挑選出這些方法:

@spam 
class Foo: 
    @marker 
    def bar(self): pass 

    def baz(self): pass 
+0

但是,裝飾者不能使用'self .__ class __.__ name__'來達到這個目的。我的意思是,該作品沒有提到裝飾者會做什麼。 –

+0

@PauloBu:一旦有約束,你已經有了課; 'type(self)',不需要去搶名字。這不是問題。 –

+0

對不起,我只是添加'.__ name__'來表達我的觀點。我指的是 - 我懷疑 - 方法裝飾器可能通過使用'self'參數來訪問方法的類。他仍然可以使用方法裝飾器並可以訪問其類。即使_類尚未被創建,當方法被執行時,裝飾器只能訪問「self .__ class__」,他可以使用它。 –