practices outer imports from best another python exception python-module shadowing

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.