Utilizzo di variabili globali in una funzione


3115

Come posso creare o usare una variabile globale in una funzione?

Se creo una variabile globale in una funzione, come posso usare quella variabile globale in un'altra funzione? Devo memorizzare la variabile globale in una variabile locale della funzione che necessita del suo accesso?

Risposte:


4248

È possibile utilizzare una variabile globale in altre funzioni dichiarandola come globalin ciascuna funzione che le assegna:

globvar = 0

def set_globvar_to_one():
    global globvar    # Needed to modify global copy of globvar
    globvar = 1

def print_globvar():
    print(globvar)     # No need for global declaration to read value of globvar

set_globvar_to_one()
print_globvar()       # Prints 1

Immagino che la ragione sia che, poiché le variabili globali sono così pericolose, Python vuole assicurarsi di sapere davvero che è ciò con cui stai giocando richiedendo esplicitamente il global parola chiave.

Vedi altre risposte se desideri condividere una variabile globale tra i moduli.


838
È estremamente esagerato riferirsi ai globi come "così pericoloso". I globi sono perfetti in ogni lingua che sia mai esistita e che esisterà. Hanno il loro posto. Quello che avresti dovuto dire è che possono causare problemi se non hai idea di come programmare.
Anthony,

207
Penso che siano abbastanza pericolosi. Tuttavia in Python le variabili "globali" sono in realtà a livello di modulo, il che risolve molti problemi.
Fábio Santos,

246
Non sono d'accordo sul fatto che Python richieda la globalparola chiave perché i globi sono pericolosi. Piuttosto, è perché la lingua non richiede che tu dichiari esplicitamente le variabili e presume automaticamente che una variabile che assegni abbia un ambito di funzione a meno che tu non lo dica diversamente. La globalparola chiave è il mezzo che viene fornito per dirlo altrimenti.
Nate CK,

7
@avgvstvs: E se stai implementando lo stesso programma senza globali, hai ancora lo stesso numero di percorsi di codice. L'argomento che hai avanzato non è contro i globali.
Corse di leggerezza in orbita,

13
@LightnessRacesinOrbit Non capisco il tuo punto. Se rimuovi una variabile globale, rimuovi il fattore complicante in quanto ora, le funzioni arbitrarie non possono più alterare lo stato del programma , in vari punti dell'esecuzione - alterando così l'esecuzione in un modo che è altrimenti impercettibile alle altre funzioni che si basano su quella variabile. Non è più necessario tenere traccia di "Lo f2()stato è cambiato, quindi ora f3()potrebbe fare qualcosa di inaspettato? Le funzioni possono ora operare agnostiche allo stato del programma esterno.
avgvstvs,

775

Se capisco correttamente la tua situazione, quello che vedi è il risultato di come Python gestisce gli spazi dei nomi locali (funzione) e globali (modulo).

Supponi di avere un modulo come questo:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

Potresti aspettarti che questo stampi 42, ma invece stampa 5. Come è già stato detto, se aggiungi una globaldichiarazione ' ' a func1(), quindi func2()stamperà 42.

def func1():
    global myGlobal
    myGlobal = 42

Quello che sta succedendo qui è che Python assume che qualsiasi nome a cui è assegnato , ovunque all'interno di una funzione, sia locale a quella funzione, a meno che non sia esplicitamente detto diversamente. Se sta leggendo solo da un nome e il nome non esiste localmente, proverà a cercare il nome in qualsiasi ambito di contenimento (ad esempio l'ambito globale del modulo).

Quando si assegna 42 al nome myGlobal, quindi, Python crea una variabile locale che ombreggia la variabile globale con lo stesso nome. Quel locale esce dal campo di applicazione e viene raccolto in modo inutile quando func1()ritorna; nel frattempo, func2()non può mai vedere altro che il nome globale (non modificato). Nota che questa decisione dello spazio dei nomi avviene al momento della compilazione, non in fase di esecuzione - se dovessi leggere il valore di myGlobalinside func1()prima di assegnarlo, otterrai una UnboundLocalError, perché Python ha già deciso che deve essere una variabile locale ma non ha ancora avuto alcun valore associato. Ma usando l' globalistruzione ' ', dici a Python che dovrebbe cercare altrove il nome invece di assegnarlo localmente.

(Credo che questo comportamento abbia avuto origine in gran parte attraverso un'ottimizzazione degli spazi dei nomi locali - senza questo comportamento, la VM di Python dovrebbe eseguire almeno tre ricerche di nomi ogni volta che viene assegnato un nuovo nome all'interno di una funzione (per assicurarsi che il nome non abbia esiste già a livello di modulo / incorporato), il che rallenterebbe in modo significativo un'operazione molto comune.)


Hai detto che la decisione sullo spazio dei nomi avviene al momento della compilazione , non penso sia vera. da quello che ho imparato la compilazione di Python verifica solo l'errore di sintassi, non l'errore di nome prova questo esempio def A (): x + = 1 , se non lo esegui, non darà UnboundLocalError , per favore verifica grazie
watashiSHUN

1
È comune usare una lettera maiuscola per variabili globali comeMyGlobal = 5
Vassilis,

3
@watashiSHUN: La decisione namespace non accadrà al momento della compilazione. Decidere che xè locale è diverso dal verificare in fase di esecuzione se il nome locale era associato a un valore prima di essere utilizzato per la prima volta.
BlackJack,

9
@Vassilis: E 'comune in maiuscolo tutte le lettere: MY_GLOBAL = 5. Consulta la Guida allo stile per il codice Python .
BlackJack

223

Potresti voler esplorare la nozione di spazi dei nomi . In Python, il modulo è il luogo naturale per i dati globali :

Ogni modulo ha una propria tabella dei simboli privata, che viene utilizzata come tabella dei simboli globale da tutte le funzioni definite nel modulo. Pertanto, l'autore di un modulo può utilizzare le variabili globali nel modulo senza preoccuparsi di scontri accidentali con le variabili globali di un utente. D'altra parte, se sai cosa stai facendo, puoi toccare le variabili globali di un modulo con la stessa notazione usata per riferirsi alle sue funzioni modname.itemname,.

Un uso specifico del global-in-a-module è descritto qui - Come posso condividere le variabili globali tra i moduli? e per completezza i contenuti sono condivisi qui:

Il modo canonico di condividere informazioni tra i moduli all'interno di un singolo programma è quello di creare un modulo di configurazione speciale (spesso chiamato config o cfg ). Basta importare il modulo di configurazione in tutti i moduli dell'applicazione; il modulo diventa quindi disponibile come nome globale. Poiché esiste solo un'istanza di ciascun modulo, qualsiasi modifica apportata all'oggetto modulo viene riflessa ovunque. Per esempio:

File: config.py

x = 0   # Default value of the 'x' configuration setting

File: mod.py

import config
config.x = 1

File: main.py

import config
import mod
print config.x

1
per un motivo che non mi piace, config.x posso liberarmene? Sono venuto con x = lambda: config.xe poi ho il nuovo valore x(). per qualche ragione, a = config.xnon avere il trucco per me.
Vladosaurus,

3
@vladosaurus lo from config import xrisolve?
jhylands,

93

Python utilizza una semplice euristica per decidere da quale ambito dovrebbe caricare una variabile, tra locale e globale. Se un nome di variabile appare sul lato sinistro di un compito, ma non è dichiarato globale, si presume che sia locale. Se non viene visualizzato sul lato sinistro di un compito, si presume che sia globale.

>>> import dis
>>> def foo():
...     global bar
...     baz = 5
...     print bar
...     print baz
...     print quux
... 
>>> dis.disassemble(foo.func_code)
  3           0 LOAD_CONST               1 (5)
              3 STORE_FAST               0 (baz)

  4           6 LOAD_GLOBAL              0 (bar)
              9 PRINT_ITEM          
             10 PRINT_NEWLINE       

  5          11 LOAD_FAST                0 (baz)
             14 PRINT_ITEM          
             15 PRINT_NEWLINE       

  6          16 LOAD_GLOBAL              1 (quux)
             19 PRINT_ITEM          
             20 PRINT_NEWLINE       
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE        
>>> 

Guarda come baz, che appare sul lato sinistro di un compito in foo(), è l'unica LOAD_FASTvariabile.


12
L'euristico cerca operazioni vincolanti . L'assegnazione è una di queste operazioni, importandone un'altra. Ma anche l'obiettivo di un forloop e il nome dopo asin withe le exceptistruzioni sono vincolati.
Martijn Pieters

@MartijnPieters Per il nome dopo asin una exceptclausola questo non era ovvio per me. Ma viene automaticamente cancellato per risparmiare memoria.
Robert

1
@Robert: non per risparmiare memoria, ma per evitare di creare un riferimento circolare, che può causare perdite di memoria. Questo perché un'eccezione fa riferimento a un traceback e il traceback fa riferimento a tutti gli spazi dei nomi locali e globali lungo l'intero stack di chiamate, inclusa la as ...destinazione nel gestore eccezioni.
Martijn Pieters

62

Se si desidera fare riferimento a una variabile globale in una funzione, è possibile utilizzare la parola chiave globale per dichiarare quali variabili sono globali. Non è necessario utilizzarlo in tutti i casi (come afferma erroneamente qualcuno qui) - se il nome a cui viene fatto riferimento in un'espressione non può essere trovato nell'ambito o negli ambiti locali nelle funzioni in cui questa funzione è definita, viene cercata tra i globali variabili.

Tuttavia, se si assegna a una nuova variabile non dichiarata come globale nella funzione, viene implicitamente dichiarata come locale e può oscurare qualsiasi variabile globale esistente con lo stesso nome.

Inoltre, le variabili globali sono utili, contrariamente ad alcuni fanatici di OOP che sostengono il contrario, specialmente per script più piccoli, in cui OOP è eccessivo.


Assolutamente ri. zeloti. La maggior parte degli utenti di Python lo usa per gli script e crea piccole funzioni per separare piccoli frammenti di codice.
Paul Uszak,

51

Se creo una variabile globale in una funzione, come posso usare quella variabile in un'altra funzione?

Possiamo creare un globale con la seguente funzione:

def create_global_variable():
    global global_variable # must declare it to be a global first
    # modifications are thus reflected on the module's global scope
    global_variable = 'Foo' 

La scrittura di una funzione non esegue effettivamente il suo codice. Quindi chiamiamo la create_global_variablefunzione:

>>> create_global_variable()

Utilizzo dei globali senza modifiche

Puoi semplicemente usarlo, purché non ti aspetti di cambiare l'oggetto a cui punta:

Per esempio,

def use_global_variable():
    return global_variable + '!!!'

e ora possiamo usare la variabile globale:

>>> use_global_variable()
'Foo!!!'

Modifica della variabile globale dall'interno di una funzione

Per puntare la variabile globale su un oggetto diverso, è necessario utilizzare nuovamente la parola chiave globale:

def change_global_variable():
    global global_variable
    global_variable = 'Bar'

Si noti che dopo aver scritto questa funzione, il codice che la modifica effettivamente non è ancora stato eseguito:

>>> use_global_variable()
'Foo!!!'

Quindi dopo aver chiamato la funzione:

>>> change_global_variable()

possiamo vedere che la variabile globale è stata cambiata. Il global_variablenome ora indica 'Bar':

>>> use_global_variable()
'Bar!!!'

Nota che "globale" in Python non è veramente globale, è solo globale a livello di modulo. Quindi è disponibile solo per le funzioni scritte nei moduli in cui è globale. Le funzioni ricordano il modulo in cui sono scritte, quindi quando vengono esportate in altri moduli, continuano a cercare nel modulo in cui sono state create per trovare le variabili globali.

Variabili locali con lo stesso nome

Se crei una variabile locale con lo stesso nome, oscurerà una variabile globale:

def use_local_with_same_name_as_global():
    # bad name for a local variable, though.
    global_variable = 'Baz' 
    return global_variable + '!!!'

>>> use_local_with_same_name_as_global()
'Baz!!!'

Ma l'uso di quella variabile locale erroneamente non cambia la variabile globale:

>>> use_global_variable()
'Bar!!!'

Nota che dovresti evitare di usare le variabili locali con gli stessi nomi dei globali a meno che tu non sappia esattamente cosa stai facendo e abbia un'ottima ragione per farlo. Non ho ancora incontrato un tale motivo.

Abbiamo lo stesso comportamento in classe

Un commento di follow-up chiede:

cosa fare se voglio creare una variabile globale all'interno di una funzione all'interno di una classe e voglio usare quella variabile all'interno di un'altra funzione all'interno di un'altra classe?

Qui dimostro che nei metodi otteniamo lo stesso comportamento delle normali funzioni:

class Foo:
    def foo(self):
        global global_variable
        global_variable = 'Foo'

class Bar:
    def bar(self):
        return global_variable + '!!!'

Foo().foo()

E adesso:

>>> Bar().bar()
'Foo!!!'

Ma suggerirei invece di utilizzare le variabili globali di utilizzare gli attributi di classe, per evitare di ingombrare lo spazio dei nomi del modulo. Nota anche che non usiamo selfargomenti qui - questi potrebbero essere metodi di classe (utile se si modifica l'attributo di classe dal solito clsargomento) o metodi statici (no selfo cls).


Fantastico, ma cosa devo fare se voglio creare una variabile globale all'interno di una funzione all'interno di una classe e voglio usare quella variabile all'interno di un'altra funzione all'interno di un'altra classe? Un po 'bloccato qui
anonmanx il

2
@anonmanx Non so perché sei bloccato, è lo stesso comportamento in un metodo come in una normale funzione. Ma aggiornerò la mia risposta con la tua osservazione e un po 'di codice demo, ok?
Aaron Hall

1
@anonmanx come va?
Aaron Hall

ok, capito. Quindi dovrò chiamare esplicitamente quella funzione per usare quella variabile globale.
anonmanx,

47

Oltre alle risposte già esistenti e per renderlo più confuso:

In Python, le variabili a cui viene fatto riferimento solo all'interno di una funzione sono implicitamente globali . Se a una variabile viene assegnato un nuovo valore in qualsiasi punto del corpo della funzione, si presume che sia locale . Se a una variabile viene mai assegnato un nuovo valore all'interno della funzione, la variabile è implicitamente locale ed è necessario dichiararla esplicitamente come "globale".

Sebbene all'inizio un po 'sorprendente, una considerazione di un momento spiega questo. Da un lato, la richiesta globale di variabili assegnate fornisce una barra contro gli effetti collaterali indesiderati. D'altra parte, se fosse necessario il globale per tutti i riferimenti globali, utilizzeresti sempre il mondo. Dovresti dichiarare come globali ogni riferimento a una funzione integrata o a un componente di un modulo importato. Questo disordine vanificherebbe l'utilità della dichiarazione globale per identificare gli effetti collaterali.

Fonte: quali sono le regole per le variabili locali e globali in Python? .


34

Con l'esecuzione parallela, le variabili globali possono causare risultati imprevisti se non si capisce cosa sta succedendo. Ecco un esempio dell'uso di una variabile globale all'interno del multiprocessing. Possiamo vedere chiaramente che ogni processo funziona con la propria copia della variabile:

import multiprocessing
import os
import random
import sys
import time

def worker(new_value):
    old_value = get_value()
    set_value(random.randint(1, 99))
    print('pid=[{pid}] '
          'old_value=[{old_value:2}] '
          'new_value=[{new_value:2}] '
          'get_value=[{get_value:2}]'.format(
          pid=str(os.getpid()),
          old_value=old_value,
          new_value=new_value,
          get_value=get_value()))

def get_value():
    global global_variable
    return global_variable

def set_value(new_value):
    global global_variable
    global_variable = new_value

global_variable = -1

print('before set_value(), get_value() = [%s]' % get_value())
set_value(new_value=-2)
print('after  set_value(), get_value() = [%s]' % get_value())

processPool = multiprocessing.Pool(processes=5)
processPool.map(func=worker, iterable=range(15))

Produzione:

before set_value(), get_value() = [-1]
after  set_value(), get_value() = [-2]
pid=[53970] old_value=[-2] new_value=[ 0] get_value=[23]
pid=[53971] old_value=[-2] new_value=[ 1] get_value=[42]
pid=[53970] old_value=[23] new_value=[ 4] get_value=[50]
pid=[53970] old_value=[50] new_value=[ 6] get_value=[14]
pid=[53971] old_value=[42] new_value=[ 5] get_value=[31]
pid=[53972] old_value=[-2] new_value=[ 2] get_value=[44]
pid=[53973] old_value=[-2] new_value=[ 3] get_value=[94]
pid=[53970] old_value=[14] new_value=[ 7] get_value=[21]
pid=[53971] old_value=[31] new_value=[ 8] get_value=[34]
pid=[53972] old_value=[44] new_value=[ 9] get_value=[59]
pid=[53973] old_value=[94] new_value=[10] get_value=[87]
pid=[53970] old_value=[21] new_value=[11] get_value=[21]
pid=[53971] old_value=[34] new_value=[12] get_value=[82]
pid=[53972] old_value=[59] new_value=[13] get_value=[ 4]
pid=[53973] old_value=[87] new_value=[14] get_value=[70]

25

Quello che stai dicendo è usare il metodo in questo modo:

globvar = 5

def f():
    var = globvar
    print(var)

f()  # Prints 5

Ma il modo migliore è usare la variabile globale in questo modo:

globavar = 5
def f():
    global globvar
    print(globvar)
f()   #prints 5

Entrambi danno lo stesso risultato.


25

A quanto pare la risposta è sempre semplice.

Ecco un piccolo modulo di esempio con un modo semplice per mostrarlo in una maindefinizione:

def five(enterAnumber,sumation):
    global helper
    helper  = enterAnumber + sumation

def isTheNumber():
    return helper

Ecco come mostrarlo in una maindefinizione:

import TestPy

def main():
    atest  = TestPy
    atest.five(5,8)
    print(atest.isTheNumber())

if __name__ == '__main__':
    main()

Questo semplice codice funziona così e verrà eseguito. Spero possa essere d'aiuto.


1
grazie, sono nuovo di Python, ma conosco un po 'di Java. quello che hai detto ha funzionato per me. e scrivere global un <ENTER> all'interno della classe .. mi sembra più sensato che all'interno di una funzione che scrive 'global a' .. noto che non puoi dire global a = 4
barlop

2
Questo è probabilmente il trucco pitone più semplice ma molto utile per me. Denominare questo modulo global_varse inizializzare i dati init_global_varsche vengono chiamati nello script di avvio. Quindi, creo semplicemente un metodo di accesso per ogni var globale definita. Spero di poter votare più volte! Grazie Peter!
swdev,

1
Cosa succede se ci sono molte variabili globali e non voglio elencarle una a una dopo una dichiarazione globale?
jtlz2,

23

È necessario fare riferimento alla variabile globale in ogni funzione che si desidera utilizzare.

Come segue:

var = "test"

def printGlobalText():
    global var #wWe are telling to explicitly use the global version
    var = "global from printGlobalText fun."
    print "var from printGlobalText: " + var

def printLocalText():
    #We are NOT telling to explicitly use the global version, so we are creating a local variable
    var = "local version from printLocalText fun"
    print "var from printLocalText: " + var

printGlobalText()
printLocalText()
"""
Output Result:
var from printGlobalText: global from printGlobalText fun.
var from printLocalText: local version from printLocalText
[Finished in 0.1s]
"""

3
'in ogni funzione che si desidera utilizzare' è leggermente errato, dovrebbe essere più vicino a: 'in ogni funzione in cui si desidera aggiornare '
spazm

21

In realtà non stai memorizzando il globale in una variabile locale, stai solo creando un riferimento locale allo stesso oggetto a cui fa riferimento il tuo riferimento globale originale. Ricorda che praticamente tutto in Python è un nome che si riferisce a un oggetto e nulla viene copiato durante le normali operazioni.

Se non fosse necessario specificare esplicitamente quando un identificatore doveva fare riferimento a un globale predefinito, si presumibilmente si dovrebbe specificare esplicitamente quando un identificatore è invece una nuova variabile locale (ad esempio, con qualcosa come il comando 'var' visto in JavaScript). Poiché le variabili locali sono più comuni delle variabili globali in qualsiasi sistema serio e non banale, il sistema di Python ha più senso nella maggior parte dei casi.

Si potrebbe avere un linguaggio che ha tentato di indovinare, usando una variabile globale se esistesse o la creazione di una variabile locale se non lo ha fatto. Tuttavia, sarebbe molto soggetto a errori. Ad esempio, l'importazione di un altro modulo potrebbe inavvertitamente introdurre una variabile globale con quel nome, modificando il comportamento del programma.


17

Prova questo:

def x1():
    global x
    x = 6

def x2():
    global x
    x = x+1
    print x

x = 5
x1()
x2()  # output --> 7


14

In seguito e come componente aggiuntivo, utilizzare un file per contenere tutte le variabili globali tutte dichiarate localmente e quindi import as:

File initval.py :

Stocksin = 300
Prices = []

File getstocks.py :

import initval as iv

def getmystocks(): 
    iv.Stocksin = getstockcount()


def getmycharts():
    for ic in range(iv.Stocksin):

1
Qual è il vantaggio di spostare le variabili globali in un altro file? È solo per raggruppare le variabili globali in un piccolo file? E perché usare la dichiarazione import ... as ...? Perché non solo import ...?
olibre

1
Ah ... ho finalmente capito il vantaggio: non c'è bisogno di usare la parola chiave global:-) => +1 :-) Modifica la tua risposta per chiarire questi interrogativi che anche altre persone potrebbero avere. Cin cin
olibre

13

Scrivere su elementi espliciti di un array globale non ha apparentemente bisogno della dichiarazione globale, sebbene scrivere "all'ingrosso" abbia quel requisito:

import numpy as np

hostValue = 3.14159
hostArray = np.array([2., 3.])
hostMatrix = np.array([[1.0, 0.0],[ 0.0, 1.0]])

def func1():
    global hostValue    # mandatory, else local.
    hostValue = 2.0

def func2():
    global hostValue    # mandatory, else UnboundLocalError.
    hostValue += 1.0

def func3():
    global hostArray    # mandatory, else local.
    hostArray = np.array([14., 15.])

def func4():            # no need for globals
    hostArray[0] = 123.4

def func5():            # no need for globals
    hostArray[1] += 1.0

def func6():            # no need for globals
    hostMatrix[1][1] = 12.

def func7():            # no need for globals
    hostMatrix[0][0] += 0.33

func1()
print "After func1(), hostValue = ", hostValue
func2()
print "After func2(), hostValue = ", hostValue
func3()
print "After func3(), hostArray = ", hostArray
func4()
print "After func4(), hostArray = ", hostArray
func5()
print "After func5(), hostArray = ", hostArray
func6()
print "After func6(), hostMatrix = \n", hostMatrix
func7()
print "After func7(), hostMatrix = \n", hostMatrix

7

Lo sto aggiungendo perché non l'ho visto in nessuna delle altre risposte e potrebbe essere utile per qualcuno alle prese con qualcosa di simile. La globals()funzione restituisce un dizionario dei simboli globale modificabile in cui è possibile "magicamente" rendere i dati disponibili per il resto del codice. Per esempio:

from pickle import load
def loaditem(name):
    with open(r"C:\pickle\file\location"+"\{}.dat".format(name), "rb") as openfile:
        globals()[name] = load(openfile)
    return True

e

from pickle import dump
def dumpfile(name):
    with open(name+".dat", "wb") as outfile:
        dump(globals()[name], outfile)
    return True

Ti consentirà semplicemente di scaricare / caricare variabili da e nello spazio dei nomi globale. Super conveniente, senza complicazioni, senza complicazioni. Abbastanza sicuro è solo Python 3.


3
globals()restituisce sempre globali disponibili nel contesto locale, quindi una mutazione qui potrebbe non riflettersi in un altro modulo.
Kiran Jonnalagadda

6

Fare riferimento allo spazio dei nomi della classe in cui si desidera visualizzare la modifica.

In questo esempio, runner utilizza max dalla configurazione del file. Voglio che il mio test cambi il valore di max quando runner lo sta usando.

principale / config.py

max = 15000

principale / runner.py

from main import config
def check_threads():
    return max < thread_count 

test / runner_test.py

from main import runner                # <----- 1. add file
from main.runner import check_threads
class RunnerTest(unittest):
   def test_threads(self):
       runner.max = 0                  # <----- 2. set global 
       check_threads()

1

I globi vanno bene, tranne che per il multiprocessing

Globali in relazione al multiprocessing su piattaforme / dispositivi diversi come Windows / Mac OS da un lato e Linux dall'altro sono problematici.

Ti mostrerò questo con un semplice esempio sottolineando un problema che ho riscontrato qualche tempo fa.

Se vuoi capire, perché le cose sono diverse su Windows / MacOs e Linux devi sapere che, il meccanismo predefinito per avviare un nuovo processo su ...

  • Windows / MacOs è "spawn"
  • Linux è 'fork'

Sono diversi nell'allocazione della memoria come un'inizializzazione ... (ma non vado qui in questo).

Diamo un'occhiata al problema / esempio ...

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)

finestre

Se lo esegui su Windows (e suppongo anche su MacOS), otterrai il seguente output ...

task 0: counter = 1
task 1: counter = 2
task 2: counter = 3
task 3: counter = 4

Linux

Se lo esegui su Linux, otterrai invece quanto segue.

task 0: counter = 1
task 1: counter = 1
task 2: counter = 1
task 3: counter = 1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.