Soy nuevo en Python, por lo que esta es probablemente una simple pregunta de alcance. El siguiente código en un archivo (módulo) de Python me confunde un poco:
if __name__ == '__main__':
x = 1
print x
En otros idiomas en los que he trabajado, este código arrojaría una excepción, ya que la x
variable es local a la if
declaración y no debería existir fuera de ella. Pero este código se ejecuta e imprime 1. ¿Alguien puede explicar este comportamiento? ¿Todas las variables creadas en un módulo son globales / están disponibles para todo el módulo?
if
declaración anterior no es verdadera (es decir, no lo__name__
es , por ejemplo, cuando importa el módulo en lugar de ejecutarlo en el nivel superior), nunca se habrá vinculado, y la declaración posterior arrojará un .'__main__'
x
print x
NameError: name 'x' is not defined
Respuestas:
Las variables de Python tienen un alcance para la función, clase o módulo más interno en el que están asignadas. Los bloques de control como
if
y loswhile
bloques no cuentan, por lo que una variable asignada dentro de unif
todavía se limita a una función, clase o módulo.(Funciones implícitas definidas por una expresión generadora o una lista / set / dict comprensión de hacer el 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 de asignación implícita.)fuente
Sí, están en el mismo "ámbito local", y en realidad un código como este es común en Python:
Tenga en cuenta que
x
no se declara o inicializa antes de la condición, como sería en C o Java, por ejemplo.En otras palabras, Python no tiene ámbitos de nivel de bloque. Sin embargo, tenga cuidado con ejemplos como
lo que claramente plantearía una
NameError
excepción.fuente
El alcance en python sigue este orden:
Buscar en el ámbito local
Busque el alcance de cualquier función de cierre
Buscar el alcance global
Buscar en los empotrados
( fuente )
Tenga en cuenta que
if
y otras construcciones de bucle / ramificación no se enumeran: solo las clases, las funciones y los módulos proporcionan alcance en Python, por lo que cualquier cosa declarada en unif
bloque tiene el mismo alcance que cualquier cosa descifrada fuera del bloque. Las variables no se verifican en tiempo de compilación, por lo que otros idiomas arrojan una excepción. En python, siempre que la variable exista en el momento que lo requiera, no se lanzará ninguna excepción.fuente
Como dijo Eli, Python no requiere declaración de variable. En C dirías:
pero en Python la declaración es implícita, por lo que cuando se asigna a x, se declara automáticamente. Es porque Python se escribe dinámicamente; no funcionaría en un lenguaje estáticamente escrito, porque dependiendo de la ruta utilizada, una variable podría usarse sin ser declarada. Esto se detectaría en el momento de la compilación en un lenguaje tipado estáticamente, pero con un lenguaje tipado dinámicamente está permitido.
La única razón por la que un lenguaje de tipo estático se limita a tener que declarar variables fuera de las
if
declaraciones debido a este problema. ¡Abraza la dinámica!fuente
A diferencia de lenguajes como C, una variable de Python está dentro del alcance de toda la función (o clase o módulo) donde aparece, no solo en el "bloque" más interno. Es como si declaraste
int x
en la parte superior de la función (o clase, o módulo), excepto que en Python no tienes que declarar variables.Tenga en cuenta que la existencia de la variable
x
se verifica solo en tiempo de ejecución, es decir, cuando llega a laprint x
declaración. Si__name__
no igualar"__main__"
a continuación, se podrían obtener una excepción:NameError: name 'x' is not defined
.fuente
Si. También es cierto para el
for
alcance. Pero no funciona, por supuesto.En su ejemplo: si la condición en la
if
declaración es falsa,x
no se definirá sin embargo.fuente
está ejecutando este código desde la línea de comandos, por
if
lo tanto, las condiciones son verdaderas yx
están establecidas. Comparar:fuente
Y tenga en cuenta que, dado que los tipos de Python solo se verifican en tiempo de ejecución, puede tener un código como:
Pero tengo problemas para pensar en otras formas en que el código funcionaría sin un error debido a problemas de tipo.
fuente