2017-12-07 7 views
1

Im folgenden Code wurden die Methoden (print_a und print_b) der Klasse Test von den zwei verschiedenen Dekorateuren dekoriert.Wie bekomme ich den Namen des Dekorators für die Funktion zur Laufzeit?

Wie kann ich feststellen, dass die angegebene Methode (sagen wir print_a), mit einem bestimmten Dekorator (decorator1) zur Laufzeit dekoriert ist?

Die einfache Lösung ist es, den Namen der Wrapper-Funktion zu ändern, das heißt die Methode wrapper-wrapper1 und wrapper2 in der Dekorateur zu ändern, aber das Problem mit dieser ist, ich habe keine Kontrolle über diesen Teil des Codes.

Hat Python eine Reflektions-API wie Java, und könnte mir das hier helfen?

def my_decorator1(func): 
    def wrapper(*args, **kwargs): 
     print('I am decorated:1') 
     func(*args, **kwargs) 
    return wrapper 

def my_decorator2(func): 
    def wrapper(*args, **kwargs): 
     print('I am decorated:2') 
     func(*args, **kwargs) 
    return wrapper 

class Test(): 

    def __init__(self, a=None, b=None): 
     self.a = a 
     self.b = b 

    @my_decorator1 
    def print_a(self): 
     print('Value of a is {}'.format(self.a)) 

    @my_decorator2 
    def print_b(self): 
     print('Value of b is {}'.format(self.b)) 


if __name__ == '__main__': 

    d = Test.__dict__ 

    f1 = d.get('print_a') 
    f2 = d.get('print_b') 

Antwort

1

Python Dekorateure sind mehr über die Umwandlung Funktionen als etwa die als einfache Metadaten Etiketten, wie man es oft tut mit Java Anmerkungen. Also, dies zu tun, würde ich den Dekorateur eine Eigenschaft auf der Funktion gesetzt wird Einwickeln (oder vielleicht wickeln Sie es in einem abrufbaren einem bestimmten Typ):

def my_decorator1(func): 
    def wrapper(*args, **kwargs): 
     print('I am decorated:1') 
     func(*args, **kwargs) 
    wrapper.decorator_name = 'my_decorator1' 
    return wrapper 

Dann:

print(Test.print_a.decorator_name) 

Alternativ können Sie in Python 3.3+ mit PEP 3155 __qualname__ den Dekorator identifizieren.

+0

Der OP sagte, er habe keinen Zugang zu den Decorator-Definitionen. – clemens

2

Da die Decorator-Funktion zur Dekorationszeit ausgeführt wird, ist es schwierig, den Namen zu erhalten. Sie können Ihr Problem mit einem zusätzlichen Dekorateur lösen. Der Dekorateur annotator schreibt in einer Eigenschaft der Funktion und Sie diesen Namen innerhalb der dekorierten Funktion lesen kann:

def annotator(decorator): 
    def wrapper(f): 
     g = decorator(f) 
     g.decorator = decorator.__name__ 
     return g 
    return wrapper 

@annotator(my_decorator1) 
def x(): 
    print x.decorator 
+0

Ich habe keinen Zugriff auf Dekorator-Code, aber ich denke, ich muss den Betreuer bitten, dies hinzuzufügen. –

+0

Wenn Sie mein Beispiel anpassen, sollte dies nicht notwendig sein, und es wird für Dekoratoren funktionieren, wo Sie den Betreuer nicht anfordern können. – clemens

+0

Gotcha, das ist neuer Dekorateur, der den eigentlichen Dekorateur anruft –

Verwandte Themen