Python-Dekorateur, der eine Funktion mit einem oder mehreren Argumenten zurückgibt

Ich möchte einen Dekorateur zu einer Reihe von Funktionen erstellen, die ein oder mehrere der Argumente der Funktionen ersetzen. Der erste Gedanke, der mir in den Sinn kam, war, einen Dekorateur zu schaffen, der ein Teil der Funktion mit den ersetzten Argumenten zurückgibt. Ich bin unglücklich mit der Art, wie die dekorierte Funktion aufgerufen wird, aber selbst wenn es "richtig" genannt wird, bekomme ich einen TypeError.

Hier ist ein Beispielcode:

def decor(func, *args, **kwargs): def _new_func(*args, **kwargs): return partial(func, *args, **kwargs, v=100) return _new_func @decor def some_function(a, v, c): return a, v, c some_function(1,2,3) # functools.partial(<function some_function at 0x7f89a8bed8c8>, 1, 2, 3, v=100) some_function(1,2,3)(1,2,3) # TypeError: some_function() got multiple values for argument 'v' 

Ich bin mir sicher, dass es einen einfachen Weg gibt, einen Dekorateur zu schaffen, der einige der Argumente ersetzt, aber noch nicht herausgefunden hat.

One Solution collect form web for “Python-Dekorateur, der eine Funktion mit einem oder mehreren Argumenten zurückgibt”

Sie müssten das Teil als Dekoregebnis zurückgeben:

 def decor(func): return partial(func, v=100) 

Allerdings setzt dies immer v=100 , auch wenn du einen anderen Wert für v nach Position bestanden hast. Du hättest doch das gleiche Problem.

Sie müssten einen Dekorateur erstellen, der weiß, welches Positionsargument v ist, und suchen Sie dort und als Keyword-Argument:

 from inspect import getargspec def decor(func): vpos = getargspec(func).args.index('v') def wrapper(*args, **kwargs): if len(args) > vpos: args = list(args) args[vpos] = 100 else: kwargs['v'] = 100 return func(*args, **kwargs) return wrapper 

Der obige Dekorator setzt das v Argument auf 100, immer . Wether hast du versucht, v als Positions-Argument oder als Keyword-Argument zu setzen, am Ende wird es sowieso auf 100 gesetzt:

 >>> @decor ... def some_function(a, v, c): ... return a, v, c ... >>> some_function(1, 2, 3) (1, 100, 3) >>> some_function(1, v=2, c=3) (1, 100, 3) 

Wenn du nur ein Default-Argument für v anlegen wolltest, wenn es nicht explizit gesetzt wäre, müsstest du die Tests umkehren:

 def decor(func): vpos = getargspec(func).args.index('v') def wrapper(*args, **kwargs): if len(args) <= vpos and 'v' not in kwargs: kwargs['v'] = 100 return func(*args, **kwargs) return wrapper 

An welchem ​​Punkt v nur vorgesehen ist, wenn noch nicht gesetzt:

 >>> @decor ... def some_function(a, v, c): ... return a, v, c ... >>> some_function(1, c=3) # v not set (1, 100, 3) >>> some_function(1, 2, c=3) # v is set (1, 2, 3) >>> some_function(1, v=2, c=3) # v is set as keyword argument (1, 2, 3) 
  • Wie kann ich alle aus einer Datei importierten Funktionen verzieren?
  • Wie man Variable in Umfang mit einem Dekorateur in Python zu injizieren
  • Wie macht man eine Kette von Funktions-Dekorateure?
  • Python - Dekorateure
  • Wie kann ich eine unbekannte Liste von Argumenten an einen Python-Dekorator schicken?
  • Wie funktioniert der @property-Dekorateur?
  • Wie können Attribute auf Funktionen überleben Wrapping?
  • Setter-Methode der Immobilien-Dekorateur nicht aufgerufen werden
  • Wie man Dekorateure wahlweise ein- oder ausschaltet
  • Umfang der Variablen in Python Dekorateur
  • Wie benutzt man Python-Dekorateure, um Funktionsargumente zu überprüfen?
  • Python ist die beste Programmiersprache der Welt.