Als ich mir das Pip-Repository auf Github angesehen habe, habe ich einen interessanten Dekorateur verwendet, also werde ich es teilen.
TL;DR
Welchen Wert hat die globale Variable beim Importieren des folgenden Pakets? Beide Funktionen "Spam" und "Ei" sind nur Funktionen zum Aktualisieren der globalen Variablen "global_variable".
mypackage/__init__.py
GLOBAL_VARIABLE = 0
def spam():
global_variable = 1
globals().update(locals())
def egg():
global global_variable
global_variable = 2
main.py
import mypackage
if __name__ == "__main__":
print(mypackage.global_variable)
Der Wert von "global_variable" hat sich seit seiner Deklaration nicht geändert, da wir nur die Funktion definieren und nicht ausführen. Das Ausführungsergebnis ist natürlich wie folgt.
$python3 main.py
0
Was passiert also, wenn Sie versuchen, die Funktion am Ende von "mypackage / __ init __. Py" aufzurufen?
mypackage/__init__.py
GLOBAL_VARIABLE = 0
def spam():
global_variable = 1
globals().update(locals())
def egg():
global global_variable
global_variable = 2
spam()
egg()
In diesem Fall wird die Funktion aufgerufen und der Wert von "global_variable" wird sowohl in "Spam" als auch in "Ei" überschrieben, sodass das Ausführungsergebnis wie folgt lautet.
$python3 main.py
2
Wenn sich bei dieser Methode jedoch die Anzahl der Funktionen erhöht, die Sie ausführen möchten, müssen Sie den Code schreiben, um so viel aufzurufen, was problematisch ist. Hier kommt der ** Dekorateur ** ins Spiel.
Hier ist das Hauptproblem. Werfen wir einen Blick auf den Code. Betrachten Sie die folgende Funktion "call_aside".
mypackage/__init__.py
global_variable = 0
def call_aside(f, *args, **kwargs):
f(*args, **kwargs)
return f
@call_aside
def spam():
global_variable = 1
globals().update(locals())
@call_aside
def egg():
global global_variable
global_variable = 2
main.py
import mypackage
if __name__ == "__main__":
print(mypackage.global_variable)
Was ist das Ausführungsergebnis?
$python3 main.py
2
Es sieht aus wie! Zuerst verstand ich den Grund dafür nicht, also war ich ziemlich besorgt. Der Mechanismus ist jedoch einfach, sobald Sie ihn verstanden haben. Konzentration auf die Funktion call_aside
,
def call_aside(f, *args, **kwargs):
f(*args, **kwargs) # <- execute f
return f
Und so weiter wird die Funktion intern aufgerufen. Daher werden beim Importieren von mypackage nur durch Ändern mit call_aside`` spam
undgg
ausgeführt, sodass sich der Wert von global_variable
wie oben gezeigt geändert hat. Selbst wenn die Anzahl der Funktionen, die Sie zum Zeitpunkt des Imports ausführen möchten, zunimmt, müssen Sie sie in diesem Fall nur dekorieren: tada:
Bei der Untersuchung von Python-Dekoratoren erklären viele, dass Dekoratoren verwendet werden, um ** "die Verarbeitung vor und nach einer bestimmten Funktion hinzuzufügen" und "eine Funktion mit vor und nach der Verarbeitung hinzugefügter Verarbeitung zurückzugeben" **. Ich denke.
def decorator(f):
def wrapper(*args, **kwargs):
print("Vorverarbeitung")
f(*args, **kwargs)
print("Nachbearbeitung")
return wrapper
Auf diese Weise wird die Wrapper-Funktion nur definiert und nicht ausgeführt. Selbst wenn Sie eine Funktion mit diesem Dekorator dekorieren, hat dies keine Auswirkungen wie das Aktualisieren des Werts der globalen Variablen, bis Sie die dekorierte Funktion aufrufen.
pypa/pip/blob/master/src/pip/_vendor/pkg_resources/__init__.py
Wenn Sie Python bis zu einem gewissen Grad lesen und schreiben können, schauen Sie sich die offiziellen Git-Hubs wie "CPython" und "Pypa" an. Es gibt unendlich viele Codes für Tsuyotsuyo-Leute, daher denke ich, dass es neue Entdeckungen und nützliche Codes geben wird.
Recommended Posts