Les décorateurs Python sont difficiles à comprendre au début. Et même si vous pensez le comprendre, ce n'est souvent pas la mise en œuvre des meilleures pratiques. En attendant, qu'est-ce que "functools.wraps" que je ne connaissais pas jusqu'à présent?
https://docs.python.jp/3/library/functools.html#functools.wraps
@functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)(Original)
Ceci est une mise à jour lors de la définition d'une fonction wrapper_wrapper()Est une fonction pratique qui appelle comme décorateur de fonction.
C'est partiel(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)Est équivalent à
Why? Si tu regardes ça, c'est un gâchis, mais ** Les noms de fonctions et les Docstrings deviendront des décorateurs ** Je me demande si cela signifie
Code de test
def hoge_decorator(f):
def hoge_wrapper(*args, **kwargs):
"""C'est le décorateur Docstring"""
print("C'est un décorateur")
return f(*args, **kwargs)
return hoge_wrapper
@hoge_decorator
def hoge_function():
"""C'est une fonction décorée Docstring"""
print("C'est la fonction décorée!")
if __name__ == '__main__':
hoge_function()
résultat
C'est un décorateur
C'est la fonction décorée!
Celui que vous voyez souvent. Il n'y a pas de problème particulier avec le mouvement.
Mais ...
def hoge_decorator(f):
def hoge_wrapper(*args, **kwargs):
"""C'est le décorateur Docstring"""
print("C'est un décorateur")
return f(*args, **kwargs)
return hoge_wrapper
@hoge_decorator
def hoge_function():
"""C'est une fonction décorée Docstring"""
print("C'est la fonction décorée!")
if __name__ == '__main__':
hoge_function()
print(hoge_function.__name__)
print(hoge_function.__doc__)
résultat
C'est un décorateur
C'est la fonction décorée!
hoge_wrapper
C'est le décorateur Docstring
Cette? C'est drôle, non? L'attribut caché sorti par print est un décorateur.
Le problème avec ceci est que le doctest ne fonctionne pas. (Je pense qu'il y a beaucoup de gens unittest ...) En outre, le fonctionnement normal peut ne pas être un problème, mais le nom n'est pas réellement le nom de la fonction en cours d'exécution. Je ne sais pas de quoi vous parlez, mais ... c'est un développement.
functools.wraps
Donc C'est là que ** functools.wraps ** entre en jeu. Utilisons-le immédiatement.
import functools
def hoge_decorator(f):
@functools.wraps(f)
def hoge_wrapper(*args, **kwargs):
"""C'est le décorateur Docstring"""
print("C'est un décorateur")
return f(*args, **kwargs)
return hoge_wrapper
@hoge_decorator
def hoge_function():
"""C'est une fonction décorée Docstring"""
print("C'est la fonction décorée!")
if __name__ == '__main__':
hoge_function()
print(hoge_function.__name__)
print(hoge_function.__doc__)
résultat
C'est un décorateur
C'est la fonction décorée!
hoge_function
C'est une fonction décorée Docstring
Ça m'a l'air bien.
doctest
Le dernier est doctest.
Au fait, si vous ne testez pas normalement et si vous réussissez le test, il n'y aura pas de journal, alors ajoutez -v
comme paramètre.
De plus, comme le test du décorateur est également exécuté, le décorateur Docstring a été supprimé.
import functools
import doctest
def hoge_decorator(f):
def hoge_wrapper(*args, **kwargs):
return f(*args, **kwargs)
return hoge_wrapper
@hoge_decorator
def hoge_function(n):
"""C'est une fonction décorée Docstring
>>> hoge_function(2)
4
"""
return n ** 2
if __name__ == '__main__':
doctest.testmod()
résultat
3 items had no tests:
__main__
__main__.hoge_decorator
__main__.hoge_function
0 tests in 3 items.
0 passed and 0 failed.
Test passed.
Après tout, le test n'est pas en cours d'exécution.
import functools
import doctest
def hoge_decorator(f):
@functools.wraps(f)
def hoge_wrapper(*args, **kwargs):
return f(*args, **kwargs)
return hoge_wrapper
@hoge_decorator
def hoge_function(n):
"""C'est une fonction décorée Docstring
>>> hoge_function(2)
4
"""
return n ** 2
if __name__ == '__main__':
doctest.testmod()
résultat
Trying:
hoge_function(2)
Expecting:
4
ok
2 items had no tests:
__main__
__main__.hoge_decorator
1 items passed all tests:
1 tests in __main__.hoge_function
1 tests in 3 items.
1 passed and 0 failed.
Test passed.
Le test a réussi correctement.
Recommended Posts