Importando un archivo py en sí mismo

Esto es test.py:

import sys a = 50 b = [1,2] def change(): print "Here 1" import test print "Here 2" test.a = -1 test.b = [0,1] return def main(): print "Here 3" change() print "Here 4" print a, b if 1: main() 

El código de Python anterior cuando se ejecuta en el sistema genera el siguiente resultado:

 Here 3 Here 1 Here 3 Here 1 Here 2 Here 4 -1 [0, 1] Here 2 Here 4 50 [1, 2] 

Lo que me confunde es que no hay un bucle infinito de salidas “Aquí 1 \ n Aquí 3”. ¿Cómo se pueden justificar los resultados de impresión a, b?

Cuando ejecuta el archivo como un script, no se considera que sea el módulo de test . Se considera que es el módulo __main__ .

Cuando la ejecución alcanza la import test , se inicia una segunda ejecución del archivo, donde el módulo se considera una test .

Cuando la ejecución alcanza nuevamente la import test , Python reconoce que ya está importando la test y no vuelve a ejecutar el módulo. En su lugar, simplemente carga el objeto del módulo de test medio inicializado en el espacio de nombres actual y continúa. La suposición optimista de Python es que ha escrito el código para que los contenidos de la test no sean necesarios hasta que finalice la importación.

Cuando la ejecución llega a las asignaciones de test.a y test.b , eso afecta el módulo de test , pero no __main__ , a pesar de que provienen del mismo archivo. Por lo tanto, la print a, b del módulo importado refleja los nuevos valores, mientras que la print a, b de __main__ refleja los valores iniciales.

Un archivo solo puede ser importado una vez. La línea de ‘prueba de importación’ tiene éxito la primera vez que se encuentra. Cuando se encuentre por segunda vez, el intérprete verificará que ya se haya cargado.

Cuando se ejecuta inicialmente un progtwig, no cuenta como ‘importado’.

El flujo general de este script es el siguiente:

  1. Se ejecuta el principal, por lo que se imprime ‘Aquí 3’
  2. Se llama cambio, por lo que se imprime ‘Aquí 1’.
  3. Al importar la prueba, Python ejecuta la función principal de la prueba.
  4. Cuando las llamadas cambian por segunda vez, Python es lo suficientemente inteligente como para saber que la prueba ya está importada, por lo que efectivamente se salta esa línea.
  5. Los principales acabados importados en ejecución.
  6. El script original termina de ejecutarse.

Si bien la excelente respuesta de user2367112 explica por qué sucede esto, ninguna de las respuestas aquí ofrece una solución alternativa.

Hay dos formas fáciles de lograr el comportamiento deseado.

  1. En lugar de importar la test , use import __main__ en import __main__ lugar. Si asigna un alias con import __main__ as test , ni siquiera tendrá que cambiar ningún otro código.
  2. Puede configurar sys.modules['test'] = sys.modules['__main__'] para decirle a python “Hey, este módulo ya existe”. Después de esto, la import test no volverá a importar el módulo, haciendo que su código funcione como se esperaba. Los documentos relevantes en sys.modules se pueden encontrar aquí .