Python-Dekorateure sind zunächst schwer zu verstehen. Und selbst wenn Sie glauben, es zu verstehen, ist es oft nicht die Best-Practice-Implementierung. Was ist "functools.wraps", das ich bis jetzt nicht kannte?
https://docs.python.jp/3/library/functools.html#functools.wraps
@functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)(Original)
Dies ist eine Aktualisierung beim Definieren einer Wrapper-Funktion_wrapper()Ist eine Komfortfunktion, die als Funktionsdekorateur aufgerufen wird.
Das ist teilweise(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)Ist äquivalent zu
Why? Wenn Sie sich das ansehen, ist es ein Chaos, aber ** Funktionsnamen und Docstrings werden zu Dekoratoren ** Ich frage mich, ob das bedeutet
Testcode
def hoge_decorator(f):
def hoge_wrapper(*args, **kwargs):
"""Es ist der Dekorateur Docstring"""
print("Es ist ein Dekorateur")
return f(*args, **kwargs)
return hoge_wrapper
@hoge_decorator
def hoge_function():
"""Es ist eine dekorierte Funktion Docstring"""
print("Dies ist die dekorierte Funktion!")
if __name__ == '__main__':
hoge_function()
Ergebnis
Es ist ein Dekorateur
Dies ist die dekorierte Funktion!
Die, die du oft siehst. Es gibt kein besonderes Problem mit der Bewegung.
Aber ...
def hoge_decorator(f):
def hoge_wrapper(*args, **kwargs):
"""Es ist der Dekorateur Docstring"""
print("Es ist ein Dekorateur")
return f(*args, **kwargs)
return hoge_wrapper
@hoge_decorator
def hoge_function():
"""Es ist eine dekorierte Funktion Docstring"""
print("Dies ist die dekorierte Funktion!")
if __name__ == '__main__':
hoge_function()
print(hoge_function.__name__)
print(hoge_function.__doc__)
Ergebnis
Es ist ein Dekorateur
Dies ist die dekorierte Funktion!
hoge_wrapper
Es ist der Dekorateur Docstring
Das? Es ist lustig, nicht wahr? Das versteckte Attribut, das von print ausgegeben wird, ist ein Dekorateur.
Das Problem dabei ist, dass doctest nicht funktioniert. (Ich denke, es gibt viele unittest Leute ...) Außerdem ist der normale Betrieb möglicherweise kein Problem, aber der Name ist nicht der Name der Funktion, die ausgeführt wird. Ich weiß nicht, wovon du sprichst, aber ... es ist eine Entwicklung.
functools.wraps
Deshalb Hier kommt ** functools.wraps ** ins Spiel. Lass es uns sofort benutzen.
import functools
def hoge_decorator(f):
@functools.wraps(f)
def hoge_wrapper(*args, **kwargs):
"""Es ist der Dekorateur Docstring"""
print("Es ist ein Dekorateur")
return f(*args, **kwargs)
return hoge_wrapper
@hoge_decorator
def hoge_function():
"""Es ist eine dekorierte Funktion Docstring"""
print("Dies ist die dekorierte Funktion!")
if __name__ == '__main__':
hoge_function()
print(hoge_function.__name__)
print(hoge_function.__doc__)
Ergebnis
Es ist ein Dekorateur
Dies ist die dekorierte Funktion!
hoge_function
Es ist eine dekorierte Funktion Docstring
Hört sich gut an.
doctest
Das letzte ist doktest. Übrigens, wenn Sie normalerweise nicht testen und den Test bestehen, gibt es kein Protokoll. Fügen Sie daher "-v" als Parameter hinzu. Da auch der Dekoratortest ausgeführt wird, wurde der Dekorations-Docstring gelöscht.
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):
"""Es ist eine dekorierte Funktion Docstring
>>> hoge_function(2)
4
"""
return n ** 2
if __name__ == '__main__':
doctest.testmod()
Ergebnis
3 items had no tests:
__main__
__main__.hoge_decorator
__main__.hoge_function
0 tests in 3 items.
0 passed and 0 failed.
Test passed.
Immerhin läuft der Test nicht.
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):
"""Es ist eine dekorierte Funktion Docstring
>>> hoge_function(2)
4
"""
return n ** 2
if __name__ == '__main__':
doctest.testmod()
Ergebnis
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.
Der Test wurde ordnungsgemäß bestanden.
Recommended Posts