2017-12-20 27 views
2

Ich arbeite mit einem Dekorator innerhalb einer Klasse, die eine Variable akzeptieren kann, und ich möchte diese Variable innerhalb der Klasse initialisieren.Initialisiere Decorator-Variable in Klasse

Unten ist ein Beispiel von dem, mit dem ich gerade arbeite (was gerade funktioniert).

_RETRIES = 3 

class MyClass(object): 
    def __init__(self, foo): 
    self._foo=foo 

    @retry.FuzzedIntervalsOnException(num_retries=_RETRIES) 
    def my_method(self): 
    return some_data 

Allerdings würde Ich mag, dies ändern etwas wie def __init__(self, foo, retries=3) zu akzeptieren Kunden zu ermöglichen, die Anzahl der Wiederholungen zu entscheiden. Die Implementierung führt jedoch zu einem undefinierten Variablenfehler.

Ich hoffe, so etwas wie die unten zu bekommen, aber wie es scheint, die richtige Antwort komplizierter sein wird, als dies:

class MyClass(object): 
    def __init__(self, foo, retries=3): 
    self._foo=foo 
    self.retries=retries 

    @retry.FuzzedIntervalsOnException(num_retries=self.retries) 
    def my_method(self): 
    return some_data 

Gibt es eine ideale Möglichkeit, eine Klassenvariable zu initialisieren verwendet werden in einem Dekorateur?

Vielen Dank im Voraus

EDIT: Weitere Informationen zu dem erneuten Versuch, unter der Initialisierung.

class FuzzedIntervalsOnException(object): 
    """Retry on exception 

    args: 
    delay: Time delay in seconds for each retry. 
    num_retries: Total number of retries. 
    """ 
    def __init__(self, delay, num_retries): 
    ... 
+1

Können Sie das Wiederholungs Dekorateur ändern von selbst zu bekommen 'num_retries' anstatt sie zu akzeptieren, in ein äußerer Anruf? –

+1

Sie können nicht auf "self.retries" im Decorator-Aufruf verweisen, da dies zur Definitionszeit der Klasse geschieht, aber es gibt kein 'self', bis Sie die Klasse instanziieren. Aber Sie können 'retry' schreiben, so dass es auf 'self' schaut, wenn die dekorierte Funktion aufgerufen wird, wenn keine' num_retries' gegeben wurde. Können Sie eine (möglicherweise skizzenhafte) Demonstration der Implementierung von 'retry' selbst geben? Im Moment zeigen Sie nichts darüber, wie "Retry" tatsächlich funktioniert. – BrenBarn

+0

Ah, das ist interessant. Ja, ich denke, dass genau das ist, worauf ich gestoßen bin und eine dieser beiden Lösungen scheint zu funktionieren. Ich werde jetzt zu meiner Frage hinzufügen, um zusätzliche Informationen über die Implementierung des Wiederholungsversuchs hinzuzufügen. – Seano314

Antwort

1

Ihre aktuellen retry sieht wahrscheinlich so etwas wie folgt aus:

def retry(num_retries=0): 
    def decorator(fn): 
     def wrapper(*args, **kwargs): 
      # ... 
     return wrapper 
    return decorator 

Sie wollen self.retries zu bekommen, aber Sie werden nicht ein Hinweis auf self bis wrapper haben aufgerufen. Der einzige Weg, dies zu tun ist, self.retries in wrapper zu bekommen. Da Sie keine Argumente an den Dekorateur vorbei sind, können Sie auch loswerden einer Schicht erhalten und etwas tun:

def retry(fn): 
    def wrapper(self, *args, **kwargs): 
     num_retries = self.retries 
     # ... 
    return wrapper 
+0

Ich hatte gehofft, dass es nicht so sein würde :) aber das macht Sinn. Vielen Dank für Ihre Hilfe, Brett! – Seano314

Verwandte Themen