Begrijp niet waarom UnboundLocalError optreedt (sluiting)

Wat doe ik hier verkeerd?

counter = 0
def increment():
  counter += 1
increment()

De bovenstaande code genereert een UnboundLocalError.


Antwoord 1, autoriteit 100%

Python heeft geen variabele declaraties, dus het moet de vinden bereikvan variabelen zelf. Het doet dit door een eenvoudige regel: als er een toewijzing is aan een variabele binnen een functie, wordt die variabele als lokaal beschouwd.[1]Dus de regel

counter += 1

maakt impliciet counterlokaal voor increment(). Als u deze regel echter probeert uit te voeren, wordt geprobeerd de waarde van de lokale variabele counterte lezen voordat deze wordt toegewezen, wat resulteert in een UnboundLocalError.[2]

Als countereen globale variabele is, wordt de globalzoekwoord zal helpen. Als increment()een lokale functie is en countereen lokale variabele, kun je nonlocalin Python 3.x.


Antwoord 2, autoriteit 48%

U moet de global statement gebruiken, zodat u de Globale variabele teller, in plaats van een lokale variabele:

counter = 0
def increment():
  global counter
  counter += 1
increment()

Als de omsluitende reikwijdte die counteris gedefinieerd, is niet de globale scope, op Python 3.x, kunt u de . In dezelfde situatie op Python 2.x zou u geen manier kunnen toewijzen aan de nonlocale naam counter, zodat u counterMODABABLE MAKEERD MAKEN EN PASSIFICEERD EN MODIGERT:

counter = [0]
def increment():
  counter[0] += 1
increment()
print counter[0]  # prints '1'

Antwoord 3, Autoriteit 15%

Om de vraag in uw onderwerpregel te beantwoorden, * Ja, er zijn sluitingen in Python, behalve dat ze alleen in een functie van toepassing zijn, en ook (in Python 2.x) zijn ze alleen-lezen; Je kunt de naam niet opnieuw binden aan een ander object (hoewel als het object is veranderd, je de inhoud kunt aanpassen). In Python 3.x kunt u de nonlocaltrefwoord om een ​​sluitvariabele te wijzigen.

def incrementer():
    counter = 0
    def increment():
        nonlocal counter
        counter += 1
        return counter
    return increment
increment = incrementer()
increment()   # 1
increment()   # 2

* De vraag stelde van oorspronkelijk om sluitingen in Python.


Antwoord 4, autoriteit 4%

De reden waarom uw code een UnboundLocalErrorgenereert, wordt al goed uitgelegd in andere antwoorden.

Maar het lijkt me dat je iets probeert te bouwen dat werkt als itertools.count().

Dus waarom probeer je het niet uit en kijk of het bij je past:

>>> from itertools import count
>>> counter = count(0)
>>> counter
count(0)
>>> next(counter)
0
>>> counter
count(1)
>>> next(counter)
1
>>> counter
count(2)

Antwoord 5, autoriteit 3%

Python heeft standaard lexicale scoping, wat betekent dat hoewel een ingesloten bereik toegang heeft tot waarden in het omsluitende bereik, het deze niet kan wijzigen (tenzij ze globaal worden verklaard met de globaltrefwoord).

Een sluiting koppelt waarden in de omsluitendeomgeving aan namen in de lokaleomgeving. De lokale omgeving kan dan de gebonden waarde gebruiken en zelfs die naam opnieuw toewijzen aan iets anders, maar kan de binding in de omsluitende omgeving niet wijzigen.

In jouw geval probeer je counterte behandelen als een lokale variabele in plaats van een gebonden waarde. Merk op dat deze code, die de waarde van xdie is toegewezen in de omsluitende omgeving bindt, prima werkt:

>>> x = 1
>>> def f():
>>>  return x
>>> f()
1

Antwoord 6, autoriteit 2%

Om een ​​globale variabele in een functie te wijzigen, moet u de globale trefwoord te gebruiken.

Wanneer u probeert om dit te doen zonder dat de regel

global counter

binnenkant van de definitie van increment, een lokale variabele met de naam teller is zo gemaakt om u te houden van het uitmesten van de teller variabele die het hele programma kan afhangen.

Merk op dat u alleen hoeft wereldwijde wanneer u het wijzigen van de variabele te gebruiken; je zou kunnen teller lezen vanuit increment zonder de noodzaak van de algemene verklaring.


Antwoord 7

Probeer dit

counter = 0
def increment():
  global counter
  counter += 1
increment()

Antwoord 8

Python niet louter lexicaal scoped.

Zie dit: een globale variabelen in functie

en dit: https: //www.saltycrane .com / blog / 2008/01 / python-variabele-scope-notes /

Other episodes