python - outer - La importación del paquete instalado desde el script genera "AttributeError: el módulo no tiene atributo" o "ImportError: no se puede importar el nombre"
python import from root directory (2)
Tengo un script llamado
requests.py
que importa el paquete de solicitudes.
El script no puede acceder a los atributos del paquete o no puede importarlos.
¿Por qué esto no funciona y cómo lo soluciono?
El siguiente código genera un
AttributeError
.
import requests
res = requests.get(''http://www.google.ca'')
print(res)
Traceback (most recent call last):
File "/Users/me/dev/rough/requests.py", line 1, in <module>
import requests
File "/Users/me/dev/rough/requests.py", line 3, in <module>
requests.get(''http://www.google.ca'')
AttributeError: module ''requests'' has no attribute ''get''
El siguiente código genera un
ImportError
.
from requests import get
res = get(''http://www.google.ca'')
print(res)
Traceback (most recent call last):
File "requests.py", line 1, in <module>
from requests import get
File "/Users/me/dev/rough/requests.py", line 1, in <module>
from requests import get
ImportError: cannot import name ''get''
O código que importa desde un módulo dentro del paquete de
requests
:
from requests.auth import AuthBase
Traceback (most recent call last):
File "requests.py", line 1, in <module>
from requests.auth import AuthBase
File "/Users/me/dev/rough/requests.py", line 1, in <module>
from requests.auth import AuthBase
ImportError: No module named ''requests.auth''; ''requests'' is not a package
Esto sucede porque su módulo local llamado
requests.py
sombrea el módulo de
requests
instalado que está tratando de usar.
El directorio actual se antepone a
sys.path
, por lo que el nombre local tiene prioridad sobre el nombre instalado.
Una sugerencia adicional de depuración cuando aparece es mirar el Traceback cuidadosamente y darse cuenta de que el nombre de su script en cuestión coincide con el módulo que está tratando de importar:
Observe el nombre que usó en su script:
File "/Users/me/dev/rough/requests.py", line 1, in <module>
El módulo que está intentando importar:
requests
Cambie el nombre de su módulo a otra cosa para evitar la colisión de nombres.
Python puede generar un archivo
__pycache__
junto a su archivo
__pycache__
(en el directorio
__pycache__
en Python 3).
Elimine eso también después de cambiarle el nombre, ya que el intérprete aún hará referencia a ese archivo y volverá a generar el error.
Sin embargo, el archivo
pyc
en
__pycache__
no
debería
afectar su código si el archivo
py
se ha eliminado.
En el ejemplo, al cambiar el nombre del archivo a
my_requests.py
, al eliminar
my_requests.py
y al ejecutarlo nuevamente se imprime correctamente
<Response [200]>
.
Para el escritor de la pregunta original, y para aquellas personas que buscan en la cadena "AttributeError: el módulo no tiene atributo", entonces la explicación común según la respuesta aceptada, es que un script creado por el usuario tiene un choque de nombres con una biblioteca nombre del archivo. Sin embargo, tenga en cuenta que el problema podría no estar en el nombre del script que genera el error (como ocurrió en el caso anterior), ni en ninguno de los nombres de los módulos de la biblioteca importados explícitamente por ese script. Puede tomar un poco de trabajo de detective descubrir qué archivo está causando el problema.
Como ejemplo para ilustrar el problema, imagine que está creando un script que usa la biblioteca "decimal" para cálculos precisos de coma flotante con números decimales, y nombra su script "
mydecimal.py
" que contiene la línea "
import decimal
" .
No hay problema con nada de eso, pero encuentra que genera este error:
AttributeError: ''module'' object has no attribute ''Number''
Esto sucedería si
previamente
hubiera escrito un script llamado "
numbers.py
" porque la biblioteca "decimal" llama a los "números" de la biblioteca estándar, pero en su lugar encuentra su script anterior.
Incluso si hubiera eliminado eso, podría no terminar el problema porque Python podría haberlo convertido en bytecode y almacenarlo en una memoria caché como "
numbers.pyc
", por lo que también tendría que buscarlo.