Globale sind in Ordnung - außer bei Multiprocessing
Globals in Verbindung mit Multiprocessing auf unterschiedlichen Plattformen/Umgebungen wie Windows/Mac OS auf der einen Seite und Linux auf der anderen Seite sind mühsam.
Ich werde Ihnen dies anhand eines einfachen Beispiels zeigen, das auf ein Problem hinweist, auf das ich vor einiger Zeit gestoßen bin.
Wenn Sie verstehen wollen, warum die Dinge unter Windows/MacOs und Linux unterschiedlich sind, dann müssen Sie wissen, dass der Standardmechanismus zum Starten eines neuen Prozesses unter ...
- Windows/MacOs ist "Laich
- Linux ist eine "Gabelung
Sie unterscheiden sich in der Speicherzuweisung und Initialisierung ... (aber darauf gehe ich hier nicht ein hier).
Werfen wir einen Blick auf das Problem/Beispiel ...
import multiprocessing
counter = 0
def do(task_id):
global counter
counter +=1
print(f'task {task_id}: counter = {counter}')
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=4)
task_ids = list(range(4))
pool.map(do, task_ids)
Windows
Wenn Sie dies unter Windows ausführen (und ich nehme an, auch unter MacOS), erhalten Sie folgende Ausgabe ...
task 0: counter = 1
task 1: counter = 2
task 2: counter = 3
task 3: counter = 4
Linux
Wenn Sie dies unter Linux ausführen, erhalten Sie stattdessen das folgende Ergebnis.
task 0: counter = 1
task 1: counter = 1
task 2: counter = 1
task 3: counter = 1
0 Stimmen
Unabhängig davon, wo Sie "global" vor dem Variablennamen erwähnt haben, kann sie überall wie eine normale lokale Variable verwendet werden, sobald Python sie als mit dem Schlüsselwort "global" gelesen hat. Aber es ist eine sehr schlechte Idee, es sei denn, die Variable ist für das gesamte Projekt gemeinsam. Zum Beispiel: project_name, database_url