L’istruzione global in Python

Aaron Meurer twitta un quiz, questo. Sembra facile, anzi troppo e essendo un quiz c’è chi –correttamente– risponde senza eseguire il codice. La maggioranza sbaglia (55%).

Adesso non vi dico come ho votato ma devo confessare che avevo già affrontato un caso simile (c’era di mezzo il Basic, non sono riuscito a ritrovarlo, peccato). Ma mi va di ravanare l’argomento. Intanto la versione originale:

# aam.py

a = 1

def maybe_inc_a(inc):
  if inc:
    global a
  a += 1

maybe_inc_a(False)
print(a

OK, cioè no, inc è False quindi quindi il blocco if non viene eseguito, provo a commentarlo ed ecco:

# aam-c.py

a = 1

def maybe_inc_a(inc):
  # if inc:
  #   global a
  a += 1

maybe_inc_a(False)
print(a)

Errore, la soluzione la da Aaron (dopo un paio di giorni):

The global statement applies to the entire function regardless where it is.

E da anche un suggerimento:

The best practice is to put global declarations at the top of the function or right before the variable is first used.

Io che vengo dal Fortran sono per il top, chi è avvezzo a C/C++ preferisce molto probabilmente l’altra posizione (for int i...).

Tratta poi altri casi ma mi basta questo. Intanto, ripensandoci c’è un comportamento un po’ particolare, cosa succede con questo codice?

# aam-g.py

st = 'ciao'
a = 1

def maybe_inc_a(inc):
  print(st)
  print(a)

maybe_inc_a(False)

Ovviamente non è possibile modificare le variabili.

In questi casi diventa importante la documentazione. Cerco per global ed ecco:

The global statement is a declaration which holds for the entire current code block. It means that the listed identifiers are to be interpreted as globals. It would be impossible to assign to a global variable without global, although free variables may refer to globals without being declared global.

Names listed in a global statement must not be used in the same code block textually preceding that global statement.

Names listed in a global statement must not be defined as formal parameters or in a for loop control target, class definition, function definition, import statement, or variable annotation.

E subito sotto segue nonlocal, mai usato ma mai dire mai (uh! l’ho detto 3 volte in questa frase 😊).

In conclusione non ho detto niente più di Aaron ma metti che i miei amici pythonisti –colpevolmente– non lo seguano su Twitter…

Posta un commento o usa questo indirizzo per il trackback.

Commenti

  • AlexKidd  Il 9 giugno 2018 alle 15:23

    Un aspetto che non avevo mai considerato!
    nonlocal è utilizzato nelle chiusure e nei decoratori

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d blogger hanno fatto clic su Mi Piace per questo: