¿Por qué funciona esto en el shell IDLE de Python pero no cuando lo ejecuto como un script de Python desde el símbolo del sistema?

Esto funciona en el shell de Python 3.3.2.

Dentro del Python 3.3.2 Shell

>>> import datetime >>> print(datetime.datetime.utcnow()) 2013-07-09 19:40:32.532341 

¡Eso es genial! Luego escribí un simple archivo de texto llamado “datetime.py”

Dentro de Datetime.py

 #Date time import datetime print(datetime.datetime.utcnow()) #Prints GMT, which is named Universal Coordinated Time # Which is UTC because in French it's something like # Universahl Tyme Coordinatay #Outputs something like 2013-07-09 15:15:19.695531 

Probando que el archivo existe

 C:\Python33\myscripts>ls __pycache__ ex1.out ex2.out ex3.py helloworld.py read1.py datetime.py ex1.py ex2.py first.py pythonintoimportexport.py test.py 

Aquí es donde se pone misterioso!

 C:\Python33\myscripts>python datetime.py Traceback (most recent call last): File "datetime.py", line 2, in  import datetime File "C:\Python33\myscripts\datetime.py", line 3, in  print(datetime.datetime.utcnow()) AttributeError: 'module' object has no attribute 'utcnow' 

Pregunta

¿Por qué funciona el mismo código en el Shell de Python, pero no cuando se ejecuta como un script?

El problema es que el archivo se está importando recursivamente, en lugar de importar la datetime módulo integrado:

Manifestación:

 $ cat datetime.py import datetime print datetime.__file__ $ python datetime.py /home/monty/py/datetime.pyc /home/monty/py/datetime.pyc 

Esto sucede porque el módulo se busca en este orden:

  • el directorio que contiene el script de entrada (o el directorio actual).
  • PYTHONPATH (una lista de nombres de directorio, con la misma syntax que la variable de shell PATH).
  • el predeterminado dependiente de la instalación.

Simplemente cambia el nombre de datetime.py a otra cosa.

Como dice @Sukrit Kalra, no use datetime.py como su nombre de archivo. Python se está confundiendo con la datetime la datetime (¡y se está importando!). Tal vez;

  $ mv datetime.py my_datetime.py 

Nunca use nombres de archivo igual que los nombres de módulos. Cambie el nombre de archivo a otra cosa aparte de datetime.py .

Poner nombre a su archivo datetime hace que Python importe el archivo que está ejecutando como un módulo. Por ejemplo, mira sys.path . El mío, por ejemplo, es ['', '/usr/lib/python3.3', ...] , lo que significa que Python se ve PRIMERO en el directorio de trabajo actual (el '' ) para los módulos. Y como todo lo que termina en .py se puede importar como un módulo, importa el script que está ejecutando (lo cual, si no me equivoco, en realidad hace que se ejecute dos veces, una vez como __main__ y una vez como módulo).