2010-05-13 13 views
156

Soy nuevo en Python, por lo que esta es probablemente una pregunta de scoping simple. El siguiente código en un archivo de Python (módulo) me confunde un poco:¿Cuál es el alcance de una variable inicializada en una instrucción if?

if __name__ == '__main__': 
    x = 1 

print x 

En otros idiomas en los que he trabajado, este código sería una excepción, ya que la variable x es local a la declaración if y debe no existir fuera de él. Pero este código se ejecuta e imprime 1. ¿Alguien puede explicar este comportamiento? ¿Están todas las variables creadas en un módulo global/disponible para todo el módulo?

+7

Otra peculiaridad que quizás no conozcas: si la instrucción 'if' anterior no es verdadera (es decir,' __name__' es * no * ''__main __'', por ejemplo, cuando importas el módulo en lugar de ejecutarlo nivel superior), entonces 'x' nunca se habrá enlazado, y la siguiente declaración' print x' arrojará un 'NameError: name 'x' no está definido'. – Santa

Respuesta

155

Las variables de Python tienen el alcance de la función, clase o módulo más interno en el que están asignadas. Los bloques de control como if y while no cuentan, por lo que una variable asignada dentro de un if todavía tiene un alcance para una función, clase o módulo.

(funciones implícitas definidos por una expresión del generador o de la lista/set comprensión/dict hacer recuento, al igual que las expresiones lambda. No se puede meter una instrucción de asignación en ninguno de ellos, pero los parámetros lambda y for objetivos son cláusula asignación implícita.)

36

sí, son de la misma "ámbito local", y en realidad un código como esto es común en Python:

if condition: 
    x = 'something' 
else: 
    x = 'something else' 

use(x) 

Tenga en cuenta que no se ha declarado x o inicializado antes de la condición, al igual que lo haría estar en C o Java, por ejemplo.

En otras palabras, Python no tiene alcances de nivel de bloque. Tenga cuidado, sin embargo, con ejemplos tales como

if False: 
    x = 3 
print(x) 

lo que elevaría claramente una excepción NameError.

1

Sí. También es cierto para el alcance for. Pero no funciones por supuesto.

En su ejemplo: si la condición en la declaración if es falsa, no se definirá x.

1

está ejecutando este código desde la línea de comandos, por lo tanto if condiciones es verdadero y x está configurado. Compare:

>>> if False: 
    y = 42 


>>> y 
Traceback (most recent call last): 
    File "<pyshell#6>", line 1, in <module> 
    y 
NameError: name 'y' is not defined 
28

Alcance en Python sigue este orden:

  • Buscar en el ámbito local

  • Buscar en el ámbito de las funciones de cerramiento

  • Buscar en el ámbito global

  • Buscar en las incorporaciones

(source)

en cuenta que if y otra de bucle/construcciones de ramificación no se enumeran - únicas clases, funciones y módulos de proporcionar alcance en Python, así que cualquier cosa declarado en un bloque de if tiene el mismo alcance como cualquier cosa declinó fuera del bloque. Las variables no se verifican en tiempo de compilación, por lo que otros lenguajes lanzan una excepción. En Python, siempre que la variable exista en el momento en que la necesite, no se lanzará ninguna excepción.

5

Como dijo Eli, Python no requiere declaración de variables.En C se diría:

int x; 
if(something) 
    x = 1; 
else 
    x = 2; 

pero en Python declaración está implícita, por lo que cuando se asigna a x se declara automáticamente. Es porque Python está tipeado dinámicamente; no funcionaría en un lenguaje estáticamente tipado, ya que dependiendo de la ruta utilizada, una variable podría usarse sin ser declarada. Esto se capturaría en tiempo de compilación en un lenguaje estáticamente tipado, pero con un lenguaje de tipeo dinámico está permitido.

La única razón por la que un lenguaje estáticamente tipado se limita a tener que declarar variables fuera de las declaraciones if debido a este problema. ¡Abraza la dinámica!

7

A diferencia de lenguajes como C, una variable de Python está en el alcance de la totalidad de la función (o clase, o módulo) donde aparece, no solo en el "bloque" más interno. Es como si declarase int x en la parte superior de la función (o clase, o módulo), excepto que en Python no tiene que declarar las variables.

Tenga en cuenta que la existencia de la variable x se comprueba solo en tiempo de ejecución, es decir, cuando se llega a la instrucción print x. Si __name__ no era igual a "__main__", entonces obtendría una excepción: NameError: name 'x' is not defined.

+0

Las clases no crean un alcance; una variable "local" en una clase simplemente se agrega al dict de la clase al momento de la creación. – chepner

Cuestiones relacionadas