Resolver intento de importación relativa sin paquete principal conocido en Python

Olorunfemi Akinlua 21 junio 2023
Resolver intento de importación relativa sin paquete principal conocido en Python

Las importaciones relativas en Python pueden ser complicadas, especialmente cuando se trata de múltiples módulos dentro de un solo directorio. Dependiendo de cómo diseñe su código base de Python, puede experimentar un ImportError.

Sin embargo, una buena comprensión del sistema de importación es suficiente para evitar tales errores, incluido el Error de importación: intento de importación relativa sin paquete principal conocido. El mensaje de error facilita la solución de problemas de dónde podría provenir el problema.

En este caso, es por la no presencia del paquete principal. Este artículo muestra y explica cómo resolver el problema ImportError.

Use submódulos para resolver el Error de importación: intento de importación relativa sin paquete principal conocido en Python

El error ImportError: intento de importación relativa sin paquete principal conocido surge cuando usamos la expresión .module_name como en el código a continuación.

import .module_name

Vamos a replicar el problema creando tres archivos dentro de un nuevo directorio. Puede usar la estructura a continuación para probarlo.

El directorio IError alberga todo el código de Python, y el directorio myPackage alberga todos los archivos del paquete. Luego, [main.py] accede a myPackage.py.

IError/
    myPackage/
        __init__.py
        myNewPackage.py
    main.py

Para recrear el mensaje de error, solo necesitamos el archivo __init__.py. El archivo __init__.py le permite al intérprete de Python saber que un directorio contiene el código del módulo de Python, en este caso, myNewPackage.py.

Antes de recrear el error, escribamos el código que estará contenido en los tres archivos de Python.

En el archivo myNewPackage.py, está presente el siguiente fragmento de código:

def createSingleDict(name, value):
    return {"name": name, "value": value}

El archivo __init__.py:

from .myNewPackage import createSingleDict

El archivo main.py, que utiliza el módulo myPackage:

import myPackage as pkg

User = pkg.createSingleDict("Jacob", 25)

print(User)

El myNewPackage.py contiene una sola función que toma dos argumentos y devuelve un diccionario con los argumentos pasados. El __init__.py utiliza la instrucción importar y las palabras clave, desde e importar para importar el myNewPackage.py al archivo __init__.py.

El main.py importa el myPackage sin usar la expresión myPackage.myNewPackage. Todo esto es posible gracias a submódulos.

El archivo __init__.py y la declaración que contiene cargan el mecanismo del submódulo donde el archivo (atributo) myNewPackage está vinculado al espacio de nombres principal (myPackage).

La parte clave de la declaración dentro del archivo __init__.py es el punto antes del nombre del módulo. Esto permite vincular el colocado al módulo principal.

Recuerde la parte del mensaje de error, sin paquete principal conocido. Esta es la razón por la que está experimentando el error.

Ejecutemos solo el archivo __init__.py. El resultado de la ejecución se muestra a continuación.

Traceback (most recent call last):
  File "c:\Users\akinl\Documents\IError\myPackage\__init__.py", line 1, in <module>
    from .myNewPackage import createSingleDict
ImportError: attempted relative import with no known parent package

Este error ocurre porque estamos ejecutando el archivo __init__.py sin el contexto del espacio de nombres principal, myPackage. Sin embargo, si ejecutamos el main.py con la sentencia import, import myPackage as pkg, no tendremos ningún error.

La salida se puede ver a continuación:

{'name': 'Jacob', 'value': 25}

Por lo tanto, no use el . operador antes de module_name a menos que esté dentro de __init__.py o el enlace o contexto de un espacio de nombres principal para evitar el ImportError: intento de importación relativa sin paquete principal conocido.

Para entender mejor lo que está pasando, si quitas el . operador dentro de la instrucción importar en __init__.py, no tendremos ningún error al ejecutar el archivo.

from myNewPackage import createSingleDict

Sin embargo, si ejecutamos el archivo main.py, provocará el siguiente error porque no hemos vinculado el módulo myNewPackage al módulo principal, myPackage.

Traceback (most recent call last):
  File "c:\Users\akinl\Documents\IError\tempCodeRunnerFile.py", line 1, in <module>
    import myPackage as pkg
  File "c:\Users\akinl\Documents\IError\myPackage\__init__.py", line 1, in <module>
    from myNewPackage import createSingleDict
ModuleNotFoundError: No module named 'myNewPackage'

Para hacer que el código se ejecute, tendremos que usar el . operador dentro de la instrucción importar en main.py y eliminar (eliminar) el archivo __init__.py.

import myPackage.myNewPackage as pkg

User = pkg.createSingleDict("Jacob", 25)

print(User)

Sin embargo, esto es engorroso y tiene más sentido vincular sus submódulos al módulo principal usando el . operador dentro de __init__.py, pero siempre asegúrese de ejecutarlo dentro del contexto principal.

Si tiene dos submódulos, funciona de la misma manera. Los nuevos submódulos otherPackage.py pueden contener el siguiente código:

def printName(name):
    print("The user's name is " + name)

Actualiza el archivo __init__.py para vincular el nuevo submódulo al espacio de nombres principal.

from .myNewPackage import createSingleDict
from .otherPackage import printName

Y dentro del main.py, tienes que usar el alias pkg para acceder a la función dentro del otro submódulo. Esa es la belleza de vincular al espacio de nombres principal, la facilidad de importación.

import myPackage as pkg

User = pkg.createSingleDict("Jacob", 25)

print(User)
pkg.printName("Jacob")

La salida del código:

{'name': 'Jacob', 'value': 25}
The user's name is Jacob

Con todo esto, tiene toda la información necesaria para prevenir o resolver el Error de importación: intento de importación relativa sin paquete principal conocido dentro de su código base de Python.

Olorunfemi Akinlua avatar Olorunfemi Akinlua avatar

Olorunfemi is a lover of technology and computers. In addition, I write technology and coding content for developers and hobbyists. When not working, I learn to design, among other things.

LinkedIn

Artículo relacionado - Python Error