tutorial lenguaje instalar descargar python

lenguaje - python tutorial



Asignación a la variable de la función primaria: "Variable local referenciada antes de la asignación" (5)

¿No se accede a ''c'' en ambos casos de ''+ ='' en funcB y ''='' en funcC?

No, funcC una nueva variable, también llamada c . = es diferente a este respecto de += .

Para obtener el comportamiento que (probablemente) quiera, ajuste la variable en una lista de elementos únicos:

def outer(): c = [0] def inner(): c[0] = 3 inner() print c[0]

imprimirá 3 .

Editar : querrás pasar c como argumento. Python 2 no tiene otra manera, AFAIK, para obtener el comportamiento deseado. Python 3 introduce la palabra clave nonlocal para estos casos.

Esta pregunta ya tiene una respuesta aquí:

Para el siguiente código de Python 2.7:

#!/usr/bin/python def funcA(): print "funcA" c = 0 def funcB(): c += 3 print "funcB", c def funcC(): print "funcC", c print "c", c funcB() c += 2 funcC() c += 2 funcB() c += 2 funcC() print "end" funcA()

Obtuve el siguiente error:

File "./a.py", line 9, in funcB c += 3 UnboundLocalError: local variable ''c'' referenced before assignment

Pero cuando comento la línea c += 3 en funcB , obtengo el siguiente resultado:

funcA c 0 funcB 0 funcC 2 funcB 4 funcC 6 end

¿No se accede a c en ambos casos de += en funcB y = en funcC ? ¿Por qué no arroja error para uno pero no para el otro?

No tengo opción de convertir c una variable global y luego declarar global c en funcB . De todos modos, el punto no es aumentar c en funcB sino por qué está funcB error para funcB y no para funcC mientras que ambos acceden a una variable local o global.


Lo que está viendo aquí es la diferencia entre acceder y asignar variables. En Python 2.x, solo puede asignar variables en el ámbito más interno o en el ámbito global (este último se realiza mediante el uso de la instrucción global). Puede acceder a variables en cualquier ámbito adjunto, pero no puede acceder a una variable en un ámbito adjunto y luego asignarlo en el ámbito más interno o global.

Lo que esto significa es que si hay alguna asignación a un nombre dentro de una función, ese nombre ya debe estar definido en el ámbito más interno antes de acceder al nombre (a menos que se haya utilizado la declaración global). En su código, la línea c += 3 es esencialmente equivalente a lo siguiente:

tmp = c c = tmp + 3

Debido a que hay una asignación a c en la función, cada otra aparición de c en esa función solo se verá en el ámbito local para funcB . Es por esto que ve el error, está intentando acceder a c para obtener su valor actual para += , pero en el ámbito local c aún no se ha definido.

En Python 3 puede solucionar este problema utilizando la instrucción no local , que le permite asignar variables que no están en el alcance actual, pero que tampoco están en el alcance global.

Su código se vería así, con una línea similar en la parte superior de funcC :

def funcB(): nonlocal c c += 3 ...

En Python 2.x esto no es una opción, y la única forma en que puede cambiar el valor de una variable no local es si es mutable.

La forma más sencilla de hacerlo es ajustar su valor en una lista, y luego modificar y acceder al primer elemento de esa lista en cada lugar donde haya utilizado el nombre de la variable anteriormente:

def funcA(): print "funcA" c = [0] def funcB(): c[0] += 3 print "funcB", c[0] def funcC(): c[0] = 5 print "funcC", c[0] print "c", c[0] funcB() funcC() funcB() funcC() print "end" funcA()

... y el resultado:

funcA c 0 funcB 3 funcC 5 funcB 8 funcC 5 end


Otra solución sucia, que, sin embargo, no requiere que hagas c global. Todo igual, pero:

def funcB(): globals()[''c''] += 3 print "funcB", c


Prueba esto:

def funcA(): print "funcA" c = 0 def funcB(c): c += 3 print "funcB", c def funcC(c): c = 5 print "funcC", c print "c", c funcB(c) funcC(c) funcB(c) funcC(c) print "end" funcA()

Y si quieres recordar el valor c entonces:

def funcA(): print "funcA" c = 0 def funcB(c): c += 3 print "funcB", c return c def funcC(c): c = 5 print "funcC", c return c print "c", c c = funcB(c) c = funcC(c) c = funcB(c) c = funcC(c) print "end" funcA()

eso producirá:

funcA c 0 funcB 3 funcC 5 funcB 8 funcC 5 end C:/Python26/


1) ¿No se accede a c en ambos casos de += en funcB y = en funcC ?

No, porque c += 3 es lo mismo que:

c = c + 3 ^ | and funcB does not know what this c is

2) No tengo la opción de convertir c una variable global y luego declarar global c en funcB .

Por favor, no hagas eso, solo cambia:

def funcB():

con:

def funcB(c):

y llame a funcB(c) más adelante en su código.

Nota: También debe cosider definir funcB y funcC fuera funcA