2010-03-01 10 views
7

Actualmente estoy desarrollando algunas cosas en Python y tengo una pregunta sobre el alcance de las variables.Corrección sobre el alcance variable

Este es el código:

a = None 
anything = False 
if anything: 
    a = 1 
else: 
    a = 2 

print a # prints 2 

Si quito la primera línea (a = None) el código sigue funcionando como antes. Sin embargo, en este caso estaría declarando la variable dentro de un bloque "if", y con respecto a otros lenguajes como Java, esa variable solo sería visible dentro del "si".

¿Cómo funciona exactamente el ámbito variable en Python y cuál es la mejor manera de programar en casos como este?

Gracias!

+2

¡No existe tal cosa como "declarar" una variable en Python! –

Respuesta

8

Como regla general, los ámbitos se crean en tres lugares:

  1. file-scope - también conocida como ámbito de módulo
  2. Clase-scope - creado dentro de class bloques
  3. Función de alcance - creado dentro def bloques

(Hay algunas excepciones a estos.)

Al asignar un nombre, se lo reserva en el espacio de nombre del alcance, marcado como no vinculado hasta que se alcanza la primera asignación.Entonces, para un modelo mental, está asignando valores a los nombres en un ámbito.

+1

En realidad, hay cuatro lugares, el cuarto es el alcance Global. Pero esto realmente depende de si considera que global es un alcance en sí mismo. – jathanism

+1

Por lo que yo entiendo alcance global, generalmente es sinónimo de alcance de archivo/módulo. Las excepciones que conozco implican pasar un diccionario para globales en 'exec' o' eval'. Desde la memoria, el cuarto ámbito se encuentra en las expresiones del generador, que no permite el escape de las variables del iterador. Y el quinto es un alcance de bloque no local para cierres: nunca he encontrado una manera fácil de explicarlo. –

+0

+1 Buena respuesta. –

2

Creo que Python usa el alcance de la función para las variables locales. Es decir, en cualquier función dada, si asigna un valor a una variable local, estará disponible desde ese momento en adelante dentro de esa función hasta que vuelva. Por lo tanto, dado que se garantiza que ambas ramas de su código se asignan a a, no es necesario asignar None al a inicialmente.

Tenga en cuenta que cuando también puede acceder a las variables declaradas en funciones externas, en otras palabras, Python tiene cierres.

def adder(first): 
    def add(second): 
     return first + second 

    return add 

Define una función llamada sumador. Cuando se invoca con un argumento first, devolverá una función que agrega cualquier argumento que reciba a first y devuelva ese valor. Por ejemplo:

add_two = adder(2) 
add_three = adder(3) 
add_two(4) # = 6 
add_three(4) # = 7 

Sin embargo, aunque se puede leer el valor de la función externa, no se puede cambiar (a diferencia de muchos otros idiomas). Por ejemplo, imagine tratar de implementar un acumulador. Es posible escribir código de esta manera:

def accumulator(): 
    total = 0 
    def add(number): 
     total += number 
     return total 
    return add 

Por desgracia, tratando de utilizar este código da como resultado un mensaje de error:

UnboundLocalError: local variable 'total' referenced before assignment 

Esto es debido a que la línea de total += number intenta cambiar el valor de total, que no puede hacerse de esta manera en Python.

+0

Puede hacer lo que necesita en su ejemplo 'accumulator()' utilizando 'nonlocal' (nuevo en Python 3). –

0

Python no necesita las variables para declararse inicialmente, por lo que puede declarar y definir en puntos arbitrarios. Y sí, el alcance es el alcance de la función, por lo que será visible fuera del if.

1

No hay problema asignando la variable en el bloque if.

En este caso, se le asigna en ambas ramas, por lo que puede ver que se definirá definitivamente cuando llegue a imprimirlo.

Si una de las ramas no asignó a a luego una excepción NameError se levante cuando intenta imprimir después de esa rama

0

estoy bastante un programador principiante, pero por lo que sé, en python las variables privadas no existen. vea private variables en la documentación de python para una discusión detallada.

información útil también se puede encontrar en la sección "ámbitos y espacios de nombres" en la misma página.

personalmente, escribo código como el que usted envió casi todos los días, sobre todo cuando la condición se basa en conseguir la entrada del usuario, por ejemplo

if len(sys.argv)==2: 
    f = open(sys.argv[1], 'r') 
else: 
    print ('provide input file') 

hago declarar las variables antes de utilizarlas por tipos estructurados , por ejemplo, declaro una lista vacía antes de agregar sus elementos dentro de un bucle.

Espero que ayude.