ModuleNotFoundError: ¿Qué significa que __main__ no es un paquete?

209

Estoy tratando de ejecutar un módulo desde la consola. La estructura de mi directorio es esta:

ingrese la descripción de la imagen aquí

Estoy tratando de ejecutar el módulo p_03_using_bisection_search.py, desde elproblem_set_02 directorio usando:

$ python3 p_03_using_bisection_search.py

El código dentro p_03_using_bisection_search.py es:

__author__ = 'm'


from .p_02_paying_debt_off_in_a_year import compute_balance_after


def compute_bounds(balance: float,
                   annual_interest_rate: float) -> (float, float):

    # there is code here, but I have omitted it to save space
    pass


def compute_lowest_payment(balance: float,
                           annual_interest_rate: float) -> float:

    # there is code here, but I have omitted it to save space
    pass    

def main():
    balance = eval(input('Enter the initial balance: '))
    annual_interest_rate = eval(input('Enter the annual interest rate: '))

    lowest_payment = compute_lowest_payment(balance, annual_interest_rate)
    print('Lowest Payment: ' + str(lowest_payment))


if __name__ == '__main__':
    main()

Estoy importando una función que está en p_02_paying_debt_off_in_a_year.py el código:

__author__ = 'm'


def compute_balance(balance: float,
                    fixed_payment: float,
                    annual_interest_rate: float) -> float:

    # this is code that has been omitted
    pass


def compute_balance_after(balance: float,
                          fixed_payment: float,
                          annual_interest_rate: float,
                          months: int=12) -> float:

    # Omitted code
    pass


def compute_fixed_monthly_payment(balance: float,
                                  annual_interest_rate: float) -> float:

    # omitted code
    pass


def main():
    balance = eval(input('Enter the initial balance: '))
    annual_interest_rate = eval(
        input('Enter the annual interest rate as a decimal: '))
    lowest_payment = compute_fixed_monthly_payment(balance,
                                                   annual_interest_rate)
    print('Lowest Payment: ' + str(lowest_payment))


if __name__ == '__main__':
    main()

Estoy teniendo el siguiente error:

ModuleNotFoundError: No module named '__main__.p_02_paying_debt_off_in_a_year'; '__main__' is not a package

No tengo idea de cómo resolver este problema. Intenté agregar un __init__.pyarchivo, pero todavía no funciona.

lmiguelvargasf
fuente
3
No es su problema, pero solo quería lanzarlo: eval(input...probablemente no sea una gran idea. Simplemente lo analizaría en lugar de abrir la oportunidad para la ejecución de código arbitrario.
Carcigenicate
2
Apuesto a que ese eval(input(...bit fue sugerido por 2to3. Tenía que hacerme eso hoy. contento de no seguirla de sugerencias blindling
ckot

Respuestas:

241

Simplemente elimine el punto para la importación relativa y haga:

from p_02_paying_debt_off_in_a_year import compute_balance_after
Moses Koledoye
fuente
56
lo resuelves ¿Por qué la importación relativa no funciona incluso si agrego __init__.py?
lmiguelvargasf
23
La respuesta aceptada no me funciona. ¿Podría ampliar la respuesta agregando una configuración de ejemplo minimalista?
Pranasas
13
Esto funciona para mí (dentro de un paquete, es decir, con un vacío __init__.pyen la misma carpeta), aunque mi PyCharm (2018.2.4) marca esto como una "Referencia no resuelta" y no puede completar automáticamente la importación.
djvg
33
@djvg - Para arreglar PyCharm puede marcar el directorio raíz como raíz de origen
Denis Yakovlev
12
Trabajar con las importaciones de Python es irritante. Es como si Python 3, PyCharm y MyPy se rieran a costa nuestra. ¿Cómo es que from ..sibling_pkg.nephew import my_functiones válido para PyCharm, pero da como resultado ValueError: attempted relative import beyond top-level packagey MyPy Cannot find module named '.sibling_pkg.nephew'(tenga en cuenta un solo "." En el error, no dos). Sin embargo, from sibling_pkg.nephew import my_functionfunciona según lo previsto, no tiene un error MyPy, pero da como resultado un error PyCharm.
ubiquibacon
86

Tengo el mismo problema que tú. Creo que el problema es que usaste importación relativa in-package import. No hay__init__.py en su directorio. Tan solo importa como Moisés respondió arriba.

Creo que el problema principal es cuando importas con un punto:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

Es equivalente a:

from __main__.p_02_paying_debt_off_in_a_year import compute_balance_after

donde se __main__refiere a su módulo actual p_03_using_bisection_search.py.


Brevemente, el intérprete no conoce la arquitectura de su directorio.

Cuando entra el intérprete p_03.py, el guión es igual a:

from p_03_using_bisection_search.p_02_paying_debt_off_in_a_year import compute_balance_after

y p_03_using_bisection_searchno contiene ningún módulo o instancia llamada p_02_paying_debt_off_in_a_year.


Así que se me ocurrió una solución más limpia sin cambiar los objetos de valor del entorno de Python (después de consultar cómo funcionan las solicitudes en la importación relativa):

La arquitectura principal del directorio es:

main.py

setup.py

---problem_set_02/

------__init__.py

------p01.py

------p02.py

------p03.py

Luego escribe en __init__.py:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

Aquí __main__está __init__, se refiere exactamente al móduloproblem_set_02 .

Luego ve a main.py:

import problem_set_02

También puede escribir un setup.pypara agregar un módulo específico al entorno.

hcnhcn012
fuente
9

Intenta ejecutarlo como:

python3 -m p_03_using_bisection_search

Dan Keder
fuente
2

Si ha creado un directorio y un subdirectorio, siga los pasos a continuación y tenga en cuenta que todo el directorio debe tener __init__.pypara que sea reconocido como un directorio.

  1. En su secuencia de comandos, incluya import sysy sys.path, podrá ver todas las rutas disponibles para Python. Debe poder ver su directorio de trabajo actual.

  2. Ahora importe el subdirectorio y el módulo respectivo que desea usar: import subdir.subdir.modulename as abcy ahora puede usar los métodos en ese módulo.

ingrese la descripción de la imagen aquí

Como ejemplo, puede ver en esta captura de pantalla que tengo un directorio principal y dos subdirectorios y en el segundo subdirectorio tengo el módulo CommonFunction. A la derecha, mi consola muestra que después de la ejecución de sys.path, puedo ver mi directorio de trabajo.

Gaurav Singh
fuente
1

Elimine el punto e importe absolute_import al comienzo de su archivo

from __future__ import absolute_import

from p_02_paying_debt_off_in_a_year import compute_balance_after
Aminah Nuraini
fuente
1

Simplemente use el nombre de la carpeta principal en la que se encuentra el archivo .py.

from problem_set_02.p_02_paying_debt_off_in_a_year import compute_balance_after
FanBek
fuente