2017-07-26 1 views
0

J'essaie de définir un décorateur qui ajoute simplement un argument mot-clé à la fonction décorée f. f peut avoir n'importe quelle combinaison de paramètres (positionnel, mot-clé, etc.). J'ai essayé ceci:Décorateur qui ajoute un paramètre de mot-clé

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 

Si je tente de l'utiliser avec une fonction qui accepte un seul argument:

@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' 

je reçois une erreur parce que le tout argument devient le paramètre name dans captured() . Comment dois-je le faire correctement?

+0

Pouvez-vous expliquer ce que « la capture() » est et ce que vous êtes vraiment essayer d'atteindre (=> le problème que vous essayez de résoudre ce - actuellement ne fonctionne pas - solution)? –

+0

Pouvez-vous s'il vous plaît effacer ce que vous passez en s et pourquoi avez-vous besoin? Cela aidera à donner une réponse plus claire. –

Répondre

0

Il suffit de passer le nom où vous appelez la fonction f = f intérieure (nom, * args, ** kwargs)

1

Vous pouvez faire un namekeyword-only argument pour y parvenir. Actuellement le problème est que c'est un argument de position et quand vous faites any_of('foo') le 'foo' est passé à l'argument name.

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" 

Démo:

>>> 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

Cela fonctionne uniquement en Python 3. –

+0

@MosesKoledoye Ils utilisent print() comme fonction dans leur code et sa sortie n'est pas un tuple. Aussi le message d'erreur 'TypeError: any_of() manquant 1 argument de position requis: 's'' est spécifique à Python 3. –

+0

Voici comment j'ai fini par le faire. J'ai simplement oublié/je ne savais pas que c'était une syntaxe valide. –