Python 3: UnboundLocalError: lokale variabele waarnaar wordt verwezen vóór toewijzing

De volgende code geeft de fout UnboundLocalError: local variable 'Var1' referenced before assignment:

Var1 = 1
Var2 = 0
def function(): 
    if Var2 == 0 and Var1 > 0:
        print("Result One")
    elif Var2 == 1 and Var1 > 0:
        print("Result Two")
    elif Var1 < 1:
        print("Result Three")
    Var1 =- 1
function()

Hoe kan ik dit oplossen? Bedankt voor alle hulp!


Antwoord 1, autoriteit 100%

U kunt dit oplossen door parameters door te geven in plaats van te vertrouwen op Globals

def function(Var1, Var2): 
    if Var2 == 0 and Var1 > 0:
        print("Result One")
    elif Var2 == 1 and Var1 > 0:
        print("Result Two")
    elif Var1 < 1:
        print("Result Three")
    return Var1 - 1
function(1, 1)

Antwoord 2, autoriteit 92%

Dit komt omdat, hoewel Var1bestaat, je ook een toewijzingsinstructie gebruikt voor de naam Var1binnen de functie (Var1 -= 1op de onderste regel). Dit creëert natuurlijk een variabele binnen het bereik van de functie genaamd Var1(naar waarheid, een -=of +=zal alleen een bestaande update (opnieuw toewijzen) variabele, maar om onbekende redenen (waarschijnlijk consistentie in deze context), behandelt Python het als een opdracht). De Python-interpreter ziet dit tijdens het laden van de module en besluit (terecht) dat de Var1van het globale bereik niet binnen het lokale bereik mag worden gebruikt, wat tot een probleem leidt wanneer u probeert te verwijzen naar de variabele ervoor wordt lokaal toegewezen.

Het gebruik van globale variabelen, buiten de noodzaak, wordt meestal afgekeurd door Python-ontwikkelaars, omdat het leidt tot verwarrende en problematische code. Als u ze echter wilt gebruiken om te bereiken wat uw code impliceert, kunt u eenvoudig toevoegen:

global Var1, Var2

bovenaan uw functie. Dit zal Python vertellen dat je niet van plan bent om een Var1of Var2variabele te definiëren binnen het lokale bereik van de functie. De Python-interpreter ziet dit tijdens het laden van de module en besluit (terecht) om eventuele verwijzingen naar de bovengenoemde variabelen op te zoeken in de globale scope.

Enkele bronnen

  • de Python-website heeft een goede uitlegvoor dit veelvoorkomende probleem.
  • Python 3 biedt een gerelateerde nonlocalverklaring – bekijk dat ook eens.

Antwoord 3, autoriteit 91%

Als je de waarde van een variabele in de functie instelt, begrijpt python dat het een lokale variabele maakt met die naam. Deze lokale variabele maskeert de globale variabele.

In jouw geval wordt Var1beschouwd als een lokale variabele en wordt het gebruikt voordat het wordt ingesteld, dus de fout.

Om dit probleem op te lossen, kun je expliciet zeggen dat het een globaal is door global Var1in je functie te plaatsen.

Var1 = 1
Var2 = 0
def function():
    global Var1
    if Var2 == 0 and Var1 > 0:
        print("Result One")
    elif Var2 == 1 and Var1 > 0:
        print("Result Two")
    elif Var1 < 1:
        print("Result Three")
    Var1 =- 1
function()

Antwoord 4, autoriteit 13%

Ik hou niet van dit gedrag, maar dit is hoe Python werkt. De vraag is al door anderen beantwoord, maar voor de volledigheid wil ik erop wijzen dat Python 2 meer van dergelijke eigenaardigheden heeft.

def f(x):
    return x
def main():
    print f(3)
    if (True):
        print [f for f in [1, 2, 3]]
main()

Python 2.7.6 retourneert een fout:

Traceback (most recent call last):
  File "weird.py", line 9, in <module>
    main()
  File "weird.py", line 5, in main
    print f(3)
UnboundLocalError: local variable 'f' referenced before assignment

Python ziet dat de fwordt gebruikt als een lokale variabele in [f for f in [1, 2, 3]], en besluit dat het ook een lokale variabele is variabele in f(3). Je zou een global fstatement kunnen toevoegen:

def f(x):
    return x
def main():
    global f
    print f(3)
    if (True):
        print [f for f in [1, 2, 3]]
main()

Het werkt; echter, f wordt 3 aan het einde…Dat wil zeggen, print [f for f in [1, 2, 3]]verandert nu de globale variabele ftot 3, dus het is geen functie meer.

Gelukkig werkt het prima in Python3 nadat je de haakjes hebt toegevoegd aan print.


Antwoord 5, autoriteit 5%

Waarom niet gewoon uw berekende waarde retourneren en de beller de globale variabele laten wijzigen. Het is geen goed idee om een globale variabele binnen een functie te manipuleren, zoals hieronder:

Var1 = 1
Var2 = 0
def function(): 
    if Var2 == 0 and Var1 > 0:
        print("Result One")
    elif Var2 == 1 and Var1 > 0:
        print("Result Two")
    elif Var1 < 1:
        print("Result Three")
    return Var1 - 1
Var1 = function()

of maak zelfs lokale kopieën van de globale variabelen en werk ermee en retourneer de resultaten die de beller vervolgens op de juiste manier kan toewijzen

def function():
v1, v2 = Var1, Var2
# calculate using the local variables v1 & v2
return v1 - 1
Var1 = function()

Other episodes