Initialisierung globaler Variablen mit Python-Dekoratoren

Einführung

Als ich mir das Pip-Repository auf Github angesehen habe, habe ich einen interessanten Dekorateur verwendet, also werde ich es teilen.

TL;DR

Globaler Variablenwert beim Import

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.

Führen Sie die Funktion im Dekorator aus

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:

Ergänzung

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.

Referenz

pypa/pip/blob/master/src/pip/_vendor/pkg_resources/__init__.py

Schließlich

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

Initialisierung globaler Variablen mit Python-Dekoratoren
Verwendung globaler Variablen in Python-Funktionen
Python-Notizen zur Verwendung von Perl-Spezialvariablen
# 1 [python3] Einfache Berechnung mit Variablen
[Python] -Variablen
[Python3] Definieren Sie globale Variablen in einer Funktion dynamisch
Die Geschichte der Manipulation globaler Python-Variablen
Starten Sie Python
Über Python Decorator
Über Python-Dekorateure
Scraping mit Python
Sturz, Python Global Declaration
Globale und lokale Variablen 2
Bearbeiten Sie Redmine mit Python Redmine
Fibonacci-Sequenz mit Python
Datenbereinigung mit Python
Verwenden von Python # externen Paketen
WiringPi-SPI-Kommunikation mit Python
Altersberechnung mit Python
Suchen Sie Twitter mit Python
Namensidentifikation mit Python
Hinweise zur Verwendung von Python-Unterprozessen
Versuchen Sie es mit Tweepy [Python2.7]
Globale und lokale Variablen 1
Berücksichtigung von Python-Dekoratoren des Typs, der Variablen übergibt
Python-Memo mit perl-ternärem Operator
Mit Python abflachen
Speichern Sie Bilder mit Python3-Anforderungen
Python: Klassen- und Instanzvariablen
[S3] CRUD mit S3 unter Verwendung von Python [Python]
[Python] Versuchen Sie, Tkinters Leinwand zu verwenden
Informationen zu Python-Variablen und -Objekten
Zeichnen Sie die globale IP mit Python auf
Verwenden von Quaternion mit Python ~ numpy-quaternion ~
Versuchen Sie es mit Kubernetes Client -Python-
[Python] Verwenden von OpenCV mit Python (Basic)
Scraping mit Python 3.5 Async-Syntax
Überwachung von Website-Änderungen mit Python
Behandeln Sie Umgebungsvariablen in Python
Mit Python auf Twitter posten
Starten Sie mit Python zu Selen
Suchalgorithmus mit word2vec [Python]
Ändern Sie die Python-Version mit pyenv
Python: Grundlagen der Verwendung von Scikit-Learn ①
Erstellen Sie JIRA-Tickets mit Python
Python-Klassen- und Instanzvariablen
Instrumentensteuerung mit Python [pyvisa]
Bearbeiten Sie Tabellenkalkulationen lokal mit Python
Python-Memo mit Perl --join
Web Scraping mit Selenium (Python)
Python-Anfängerhandbuch (Variationen / Arrays)
[Python] Validierung von JSON mit Voluptuous
Python-Variablen und Objekt-IDs
Deklaration globaler Variablen der C-Sprache
Online-Übertragung mit Python
Datenanalyse mit Python-Pandas
Übersetzt mit Googletrans in Python