Sur Ian McCracken's blog, il a un article where he talks about decorator factory factories. Dans l'article, il donne un exemple de:Python autorise-t-il les appels aux usines d'usine de décoration?
def decorator_factory_factory(method):
def decorator_factory(regex):
def decorator(f):
def inner(*args, **kwargs):
# do stuff with f(*args, **kwargs)
# and method and regex
return inner
return decorator
return decorator_factory
Il donne alors un exemple de la façon dont il pourrait appeler le décorateur:
@decorator_factory_factory('GET')('^/.*$')
def onGetAnything(self):
pass
Cela a attiré mon attention. Je ne l'avais jamais essayé d'appeler une usine de décorateur de décorateur avant, donc j'ai décidé de voir comment le code se comporterait:
>>> def decorator_factory_factory(method):
def decorator_factory(regex):
def decorator(f):
def inner(*args, **kwargs):
print(args, kwargs)
return inner
return decorator
return decorator_factory
>>> @decorator_factory_factory('GET')('^/.*$')
def onGetAnything(self):
pass
SyntaxError: invalid syntax
>>>
Comme vous pouvez le voir ci-dessus, Python déclenche une SyntaxError
. Pourquoi donc? En plus du code qui semble fonctionner pour M. McCraken, il semble que le code devrait fonctionner parfaitement bien. N'est-ce pas fondamentalement la même syntaxe que l'enchaînement des appels de fonction, qui fonctionne? par exemple:
>>> def foo():
def bar():
return 2
return bar
>>> foo()()
2
>>>
Je pensais que peut-être qu'il utilisait une ancienne version de Python qui a permis à cette syntaxe, donc je regardais la grammaire pour la version Python qu'il était probablement en utilisant quand il a écrit l'article en 2009; 2.6.9. Mais the grammar ne semble pas encore pour permettre décorateur enchaînée appelle:
decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE decorators: decorator+ decorated: decorators (classdef | funcdef)
a cette syntaxe jamais été autorisée dans une version Python. Si non, comment Ian a-t-il pu exécuter son code? At-il simplement fait une erreur?
Il est presque certain que seule la coque indentant la définition de la fonction. Faites cela dans un fichier à la place. –
@DanielRoseman Non. [Cela génère toujours une erreur] (https://repl.it/JJxJ/0). –
Je ne pense pas que cet exemple fourni dans l'article est valide.Une fabrique de décorateurs peut être utilisée pour générer un décorateur 'GET = decorator_factory_factory ('GET')' -> '@GET ('regex')', mais je ne pense pas qu'il soit possible d'utiliser les décorateurs comme décrit par l'auteur. Probablement c'est trompeur. Je serais heureux d'avoir tort et d'obtenir l'explication détaillée, mais cela ne ressemble pas à un comportement python «out of the box». –