2017-06-12 31 views
0

我有問題,解決這個問題,我有下面的類:工作和getattr的

class test: 

    @auth 
    def method1(self, x): 
     return x 

    @auth 
    def method2(self, x, y): 
     return x+y 

    def method3(self, z): 
     return z 

我申請的裝飾在這兩種方法,如下:

class auth: 

    def __init__(self, f): 
     self.f = f 

    def __call__(self, *args, **kwargs): 
     self.f(*args, **kwargs) 

到目前爲止沒有問題,不過,我需要(需要)使用下面的代碼:

def run(): 
    klass = globals()["test"]() 

    method1 = getattr(klass, "method1") 
    print(method1.__code__.co_varnames) 
    # should print (self, x) 

    method2 = getattr(klass, "method2") 
    print(method2.__code__.co_varnames) 
    # should print (self, x, y) 

    method3 = getattr(klass, "method3") 
    print(method3.__code__.co_varnames) 
    # i get (self, z) < without decorator 

但我現在得到:

AttributeError: 'auth' object has no attribute '__code__' 

如果我們認爲方法「method1和method2」的簽名現在是「auth」,那麼有意義。

那麼,如何獲得有或沒有裝飾器的參數。 我開始閱讀有關「檢查」的內容,但有很多關於緩慢的報道。

+0

你可以使用像'method1.f .__ code __。co_varnames'這樣的東西。但是通常你需要使用的代碼需要知道/與裝飾器代碼協作(即它需要知道在哪裏尋找函數參數)。 – BrenBarn

回答

1

「原始」方法存儲在auth對象的f屬性中。取而代之的method1.__code__.co_varnames使用method1.f.__code__.co_varnames

+0

愛你兄弟!有可能知道一個方法是否有裝飾器? (只是一個小問題) – Jonny

+0

我不確定,但[this](https://stackoverflow.com/questions/19314405/how-to-detect-is-decorator-has-been-applied-to-method-或功能)可能在某處開始 –

+0

謝謝,我可以使用__code__!=無,而是像鏈接inspect.getargspec,但無論如何感謝的人。 – Jonny

1

註解只包含一個對象,不是對象itsself,它是auth類的一個對象,而不是function。要自己訪問該功能,可以編寫methodN.f.__code__.co_varnames或將該函數的__dict__對象的副本分配給自己的驗證對象。

class auth: 

    def __init__(self, f): 
     self.__dict__.update(f.__dict__) 
     # now the initialisations 
     self.f = f 

    def __call__(self, *args, **kwargs): 
     self.f(*args, **kwargs) 

編輯: 你應該初始化成員/調用super更新字典之後,因爲f可以通過更新,如被覆蓋。你定義了另一個裝飾者類,它也有一個成員f

+0

謝謝,它已解決,並與字典更新很好的解決方法 – Jonny