2017-07-26 3 views
0

Ich versuche, einen Dekorator zu definieren, der der verzierten Funktion f nur ein Schlüsselwortargument hinzufügt. f kann eine beliebige Kombination von Parametern (Position, Schlüsselwort usw.) enthalten. Ich versuchte dies:Decorator, der einen Schlüsselwortparameter hinzufügt

def capture_wrap(f): 
    def captured(name=False, *args, **kwargs): 
     """name can be False, True or str. if str, then use it as a name.""" 
     print (name, f, args, kwargs) 
     inner = f(*args, **kwargs) 
     if name is False: 
      return inner 
     elif name is True: 
      return capture(inner) 
     else: 
      return capture(inner, name=name) 
    return captured 

Wenn ich versuche es mit einer Funktion zu verwenden, die ein einzelnes Argument akzeptiert:

@capture_wrap 
def any_of(s): 
    """s must be in the right format. 
    See https://docs.python.org/3/library/re.html#regular-expression-syntax .""" 
    return wrap('[', Dinant(s, escape=False), ']') 
0-9A-Fa-f <function any_of at 0x7fb370548a60>() {} 
Traceback (most recent call last): 
File "./dinant.py", line 222, in <module> 
    hex = one_or_more(any_of('0-9A-Fa-f')) 
File "./dinant.py", line 116, in captured 
    inner = f(*args, **kwargs) 
TypeError: any_of() missing 1 required positional argument: 's' 

Ich erhalte eine Fehlermeldung, weil das ein Argument der name Parameter werden in captured() . Wie soll ich das richtig machen?

+0

Können Sie uns erklären, was "capture()" ist und was Sie wirklich erreichen wollen (=> das Problem Sie versuchen, mit diesem zu lösen - aktuell funktioniert nicht - Lösung)? –

+0

Können Sie bitte klarstellen, was Sie in s übergeben und warum brauchen Sie es? Dies wird helfen, eine klarere Antwort geben –

Antwort

0

Geben Sie einfach Name, wo Sie die Funktion f Innen = f rufen (Name, * args, ** kwargs)

1

Sie name ein keyword-only argument dies zu erreichen machen. Derzeit ist das Problem, dass es ein Positionsargument ist und wenn Sie any_of('foo') tun, wird das an name Argument übergeben.

def capture_wrap(f): 
    def captured(*args, name=False, **kwargs): 
     """name can be False, True or str. if str, then use it as a name.""" 
     print(name, f, args, kwargs) 
     inner = f(*args, **kwargs) 
     return inner 
    return captured 


@capture_wrap 
def any_of(s1, s2, s3, **kwargs): 
    return "I do something" 

Demo:

>>> any_of('0-9A-Fa-f', 1, 2) 
False <function any_of at 0x1041daea0> ('0-9A-Fa-f', 1, 2) {} 
'I do something' 

>>> any_of('0-9A-Fa-f', 2, 3, a=1, b=2, name='some-name') 
some-name <function any_of at 0x1041daea0> ('0-9A-Fa-f', 2, 3) {'a': 1, 'b': 2} 
'I do something' 
+0

Dies funktioniert nur in Python 3. –

+0

@MosesKoledoye Sie verwenden print() als Funktion in ihrem Code und seine Ausgabe ist kein Tupel. Auch die Fehlermeldung 'TypeError: any_of() fehlt 1 benötigt positional Argument: 's'ist Python 3 spezifisch. –

+0

So habe ich es tatsächlich gemacht. Ich habe einfach vergessen/wusste nicht, dass das eine gültige Syntax war. –