Esta es la primera vez que realmente me siento y probé python 3, y parece que estoy fallando miserablemente. Tengo los siguientes dos archivos:
config.py tiene algunas funciones definidas en él, así como algunas variables. Lo he reducido a lo siguiente:
config.py
debug = True
prueba.py
import config print (config.debug)
También tengo un __init__.py
Sin embargo, recibo el siguiente error:
ModuleNotFoundError: No module named 'config'
Soy consciente de que la convención py3 es usar importaciones absolutas:
from . import config
Sin embargo, esto conduce al siguiente error:
ImportError: cannot import name 'config'
Así que no sé qué hacer aquí... Cualquier ayuda es muy apreciada. :)
TL; DR: No puede hacer importaciones relativas desde el archivo que ejecuta ya que el módulo __main__
no es parte de un paquete.
Importaciones absolutas : importe algo disponible en sys.path
Importaciones relativas : importe algo relativo al módulo actual, debe ser parte de un paquete
Si está ejecutando ambas variantes exactamente de la misma manera, una de ellas debería funcionar. Aquí hay un ejemplo que debería ayudarlo a comprender lo que está sucediendo. Agreguemos otro archivo main.py
con la estructura general de directorios como esta:
. ./main.py ./ryan/__init__.py ./ryan/config.py ./ryan/test.py
Y actualicemos test.py
para ver qué está pasando:
# config.py debug = True
# test.py print(__name__) try: # Trying to find module in the parent package from . import config print(config.debug) del config except ImportError: print('Relative import failed') try: # Trying to find module on sys.path import config print(config.debug) except ModuleNotFoundError: print('Absolute import failed')
# main.py import ryan.test
test.py
primero:
$ python ryan/test.py __main__ Relative import failed True
Aquí "test" es el módulo __main__
y no sabe nada acerca de pertenecer a un paquete. Sin embargo, la import config
debería funcionar, ya que la carpeta ryan
se agregará a sys.path
.
main.py
en su lugar:
$ python main.py ryan.test True Absolute import failed
Y aquí la prueba está dentro del paquete "ryan" y puede realizar importaciones relativas. la import config
falla ya que las importaciones relativas implícitas no están permitidas en Python 3.
Espero que esto haya ayudado.
PD: si te quedas con Python 3, ya no necesitas los archivos __init__.py
.
Me lo imaginé. Muy frustrante, especialmente viniendo de python2.
Tienes que agregar un .
al módulo, independientemente de que sea o no relativo o absoluto.
Creé la configuración del directorio de la siguiente manera.
/main.py --/lib --/__init__.py --/mody.py --/modx.py
modx.py
def does_something(): return "I gave you this string."
mody.py
from modx import does_something def loaded(): string = does_something() print(string)
principal.py
from lib import mody mody.loaded()
cuando ejecuto main, esto es lo que sucede
$ python main.py Traceback (most recent call last): File "main.py", line 2, in <module> from lib import mody File "/mnt/c/Users/Austin/Dropbox/Source/Python/virtualenviron/mock/package/lib/mody.py", line 1, in <module> from modx import does_something ImportError: No module named 'modx'
Ejecuté 2to3, y el resultado principal fue este
RefactoringTool: Refactored lib/mody.py --- lib/mody.py (original) +++ lib/mody.py (refactored) @@ -1,4 +1,4 @@ -from modx import does_something +from .modx import does_something def loaded(): string = does_something() RefactoringTool: Files that need to be modified: RefactoringTool: lib/modx.py RefactoringTool: lib/mody.py
Tuve que modificar la declaración de importación de mody.py para solucionarlo
try: from modx import does_something except ImportError: from .modx import does_something def loaded(): string = does_something() print(string)
Luego ejecuté main.py nuevamente y obtuve el resultado esperado
$ python main.py I gave you this string.
Por último, solo para limpiarlo y hacerlo portátil entre 2 y 3.
from __future__ import absolute_import from .modx import does_something
Debe agregar la ruta de su proyecto a PYTHONPATH
y asegurarse de usar importaciones absolutas .
Para UNIX (Linux, OSX,...)
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
Para ventanas
set PYTHONPATH=%PYTHONPATH%;C:\path\to\your\project\
Importaciones absolutas
Suponiendo que tenemos la siguiente estructura de proyecto,
└── myproject ├── mypackage │ ├── __init__.py │ ├── a.py └── anotherpackage ├── __init__.py ├── b.py ├── c.py └── mysubpackage ├── __init__.py └── d.py
solo asegúrese de hacer referencia a cada importación a partir del directorio raíz del proyecto. Por ejemplo,
# in module a.py import anotherpackage.mysubpackage.d # in module b import anotherpackage.c import mypackage.a
Para obtener una explicación más completa, consulte el artículo Cómo corregir ModuleNotFoundError e ImportError