Ich habe einen Dekorateur wie unten.
def myDecorator(test_func):
return callSomeWrapper(test_func)
def callSomeWrapper(test_func):
return test_func
@myDecorator
def someFunc():
print 'hello'
Ich möchte diesen Dekorateur verbessern, um ein anderes Argument wie das folgende zu akzeptieren
def myDecorator(test_func,logIt):
if logIt:
print "Calling Function: " + test_func.__name__
return callSomeWrapper(test_func)
@myDecorator(False)
def someFunc():
print 'Hello'
Aber dieser Code gibt den Fehler,
TypeError: myDecorator () akzeptiert genau 2 Argumente (1 angegeben)
Warum wird die Funktion nicht automatisch übergeben? Wie übergebe ich die Funktion explizit an die Dekorationsfunktion?
Antworten:
Da Sie den Dekorator wie eine Funktion aufrufen, muss eine andere Funktion zurückgegeben werden, die der eigentliche Dekorator ist:
Die äußere Funktion erhält alle Argumente, die Sie explizit übergeben, und sollte die innere Funktion zurückgeben. Der inneren Funktion wird die zu dekorierende Funktion übergeben und die geänderte Funktion zurückgegeben.
Normalerweise soll der Dekorateur das Funktionsverhalten ändern, indem er es in eine Wrapper-Funktion einwickelt. Hier ist ein Beispiel, das optional die Protokollierung hinzufügt, wenn die Funktion aufgerufen wird:
Der
functools.wraps
Aufruf kopiert Dinge wie den Namen und die Dokumentzeichenfolge in die Wrapper-Funktion, um sie der ursprünglichen Funktion ähnlicher zu machen.Anwendungsbeispiel:
quelle
functools.wraps
ist ratsam - der ursprüngliche Name, die Dokumentzeichenfolge usw. der umschlossenen Funktion bleiben erhalten.myDecorator
hier) auch als Dekorateur bezeichnen. Dies ist praktisch für einen Benutzer des Dekorateurs, kann jedoch verwirrend sein, wenn Sie versuchen, einen zu schreiben.log_decorator
ein Standardargument verwenden, das Sie nicht verwenden können@log_decorator
, muss es sein@log_decorator()
Nur um einen anderen Standpunkt zu bieten: die Syntax
ist äquivalent zu
Insbesondere
expr
kann alles sein, was Sie möchten, solange es zu einem Callable ausgewertet wird. In bestimmten Insbesondereexpr
kann ein Dekorateur Werk sein: Sie geben es einige Parameter und es gibt Ihnen einen Dekorateur. Vielleicht ist ein besserer Weg, Ihre Situation zu verstehen, alswas dann auf gekürzt werden kann
Da es so aussieht, als wäre
decorator_factory
es ein Dekorateur, neigen die Leute dazu, es zu benennen, um dies widerzuspiegeln. Dies kann verwirrend sein, wenn Sie versuchen, den Indirektionsebenen zu folgen.quelle
Ich möchte nur einen nützlichen Trick hinzufügen, mit dem Dekorationsargumente optional gemacht werden können. Es ermöglicht auch die Wiederverwendung des Dekorators und die Verringerung der Verschachtelung
quelle
Nur eine andere Art, Dekorateure zu machen. Ich finde diesen Weg am einfachsten, meinen Kopf herumzuwickeln.
quelle
Wenn Sie nun eine Funktion
function1
mit einem Dekorator aufrufen möchtendecorator_with_arg
und in diesem Fall sowohl die Funktion als auch der Dekorator Argumente annehmen,quelle