2016-07-19 58 views
2

我想訪問要在其上定義方法的類。例如,這可以用來爲裝飾器的方法創建別名。這種特殊情況可以在不使用裝飾器的情況下實現(alias = original_name),但我想使用裝飾器,主要是因爲別名可以在頂部的方法定義的旁邊可見,在方法定義很長時很有用。在定義方法時從方法訪問python類

def method_alias(*aliases): 
    def aliased(m): 
     class_of_m = ??? # GET class of this method 
     for alias in aliases: 
      setattr(class_of_m, alias, m) 
     return m 
    return aliased 

class Test(): 
    @method_alias('check', 'examine') 
    def test(): 
     print('I am implemented with name "test"') 

後來我發現here,上述可通過使用兩個裝飾(第一存儲的別名方法屬性,後來已經創建的類的情況下,屬性添加到類)來實現。它可以在沒有裝飾課程的情況下完成,即只是裝飾該方法?這需要訪問裝飾器中的類名稱。

回答

0

簡短的回答是否定的。類對象的內容在創建類對象之前進行評估,即創建函數test並將其傳遞給裝飾器,而不存在類Test。裝飾者因此無法獲得對其的引用。

爲了解決方法走樣的問題,我覺得三種方法:通過您的鏈接描述

  • 使用類裝飾。
  • 使用元類,它允許您在創建類對象之前修改類'__dict__。 (實現一個元類實際上覆蓋了類對象的默認構造函數,請參閱here。另外,Python 3中的元類使用語法已更改。)
  • Test的每個實例的__init__方法中創建別名。

第一種方法可能是最直接的。我寫了另一個例子。它基本上和你的鏈接一樣,但是爲了使它更清晰一點,它更加簡潔。

def alias(*aliases): 
    def decorator(f): 
     f.aliases = set(aliases) 
     return f 
    return decorator 

def apply_aliases(cls): 
    for name, elem in list(cls.__dict__.items()): 
     if not hasattr(elem, 'aliases'): 
      continue 
     for alias in elem.aliases: 
      setattr(cls, alias, elem) 
    return cls 

@apply_aliases 
class Test(object): 
    @alias('check', 'examine') 
    def test(self): 
     print('I am implemented with name "test"') 

Test().test() 
Test().check() 
Test().examine()