2017-04-27 17 views
1

爲了更好的封裝,我想用相同類中的方法來裝飾實例方法。在python中,我可以訪問類作用域中的方法(但不在函數範圍內)

class SomeClass(object): 

    @staticmethod 
    def some_decorator(func): 
     def wrapped(self): 
      print 'hello' 
      return func(self) 
     return wrapped 

    @some_decorator 
    def do(self): 
     print 'world' 

x = SomeClass() 
x.do() 

然而,這段代碼引發TypeError: 'staticmethod' object is not callable

現在我做一個變通方法通過定義一個類,重載其方法模擬功能,但它最終還是一類,而不是一個函數。

那麼我可以在類範圍內訪問我的函數嗎?

+1

[Python的裝飾作爲一個靜態方法(可能的重複http://stackoverflow.com/questions/6412146/python-decorator-as-a-staticmethod) – julienc

回答

2

只是擺脫@staticmethod線。你想some_decorator行爲像一個普通的函數,而不是像某種方法。

在類對象本身存在之前,正在執行類定義時調用裝飾器。一個類中的常規方法定義實際上只是普通的舊函數,每次被稱爲類實例的屬性(將它們變成綁定方法)時,它們都會動態地變爲方法。但是,在構建類對象本身時,可以將它們視爲普通函數。

class SomeClass(object): 
    def some_decorator(func): 
     def wrapped(self): 
      print 'hello' 
      return func(self) 
     return wrapped 

    @some_decorator 
    def do(self): 
     print 'world' 

x = SomeClass() 
x.do() 

輸出

hello 
world 

順便說一句,你有你裝飾了一個錯誤:它返回wrapped()而不是wrapped


由於chepner提到的意見,我們可以刪除some_decorator這樣經過我們在類定義使用完它不佔用空間的類對象。 (如果我們不小心嘗試調用它,我們會得到一個錯誤)。我們可以類定義後做del SomeClass.some_decorator,但它也是完全有效的把del聲明的類定義:

class SomeClass(object): 
    def some_decorator(func): 
     def wrapped(self): 
      print 'hello' 
      return func(self) 
     return wrapped 

    @some_decorator 
    def do(self): 
     print 'world' 

    del some_decorator 
+0

謝謝你的糾正!我沒想到解決方案如此簡單...... – zstbsqx

+1

如果您不想混亂您的類的名稱空間,可以將'del some_decorator'添加到類定義的末尾。定義'do'後,您不再需要它了。 – chepner

+0

@chepner好點。我原本沒有打擾,因爲很難在不提高TypeError的情況下將其稱爲類定義以外的內容,但我認爲清除它會更清晰。 –

相關問題