ModuleNotFoundError:__main__がパッケージでないとはどういう意味ですか?


208

コンソールからモジュールを実行しようとしています。私のディレクトリの構造はこれです:

ここに画像の説明を入力してください

私はモジュールを実行しようとしていますp_03_using_bisection_search.pyから、problem_set_02使用してディレクトリ:

$ python3 p_03_using_bisection_search.py

内部のコードp_03_using_bisection_search.pyは次のとおりです。

__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()

私はp_02_paying_debt_off_in_a_year.pyコードが含まれている関数をインポートしています:

__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()

次のエラーが発生します。

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

この問題の解決方法はわかりません。__init__.pyファイルを追加しようとしましたが、まだ機能しません。


3
あなたの問題ではありませんが、私はそれをそこに捨てたかっただけeval(input...です。おそらく素晴らしいアイデアではありません。任意のコード実行の機会を開くのではなく、単に解析するだけです。
発がん性物質2017年

2
そのeval(input(...ビットは2to3によって提案されたに違いない。今日はそれをしてもらいました。目立たない提案に従っていないのがうれしい
ckot

回答:


238

相対インポートのドットを削除して、次のようにします。

from p_02_paying_debt_off_in_a_year import compute_balance_after

56
あなたはそれを解決します。追加しても相対インポートが機能しないのはなぜ__init__.pyですか?
lmiguelvargasf 2017年

23
受け入れられた答えは私のために働いていません。最小限の例の設定を追加することで、答えを拡張できますか?
Pranasas

13
__init__.pyPyCharm(2018.2.4)はこれを「未解決の参照」としてマークし、インポートのオートコンプリートに失敗しますが、これは私にとって(パッケージ内、つまり同じフォルダーに空がある場合)機能します。
djvg 2018年

33
@djvg-PyCharmを修正するには、ルートディレクトリをソースルートとしてマークすることができます
Denis Yakovlev

12
Pythonのインポートを操作するのは腹立たしいです。Python 3、PyCharm、MyPyのすべてが私たちの費用で大笑いしています。それがfrom ..sibling_pkg.nephew import my_functionPyCharmに有効であるが、結果はValueError: attempted relative import beyond top-level packageとMyPyですCannot find module named '.sibling_pkg.nephew'(エラーには「。」が2 つではなく1つあることに注意してください)。しかし、from sibling_pkg.nephew import my_function意図したとおりに機能し、MyPyエラーはありませんが、PyCharmエラーが発生します。
ubiquibacon

85

あなたと同じ問題があります。問題は、で相対インポートを使用したことだと思いますin-package import__init__.pyあなたのディレクトリにはありません。したがって、モーセが上記で答えたように、インポートしてください。

私が考える中心的な問題は、ドットでインポートするときです:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

これは次と同等です。

from __main__.p_02_paying_debt_off_in_a_year import compute_balance_after

__main__現在のモジュールを指しますp_03_using_bisection_search.py


簡単に言うと、インタプリタはディレクトリアーキテクチャを認識していません。

インタープリターがに入るとp_03.py、スクリプトは次のようになります。

from p_03_using_bisection_search.p_02_paying_debt_off_in_a_year import compute_balance_after

p_03_using_bisection_search呼ばれるモジュールやインスタンスは含まれていませんp_02_paying_debt_off_in_a_year


だから私は(相対インポートでリクエストがどのように行われるかを調べた後)Python環境の貴重品を変更することなく、よりクリーンなソリューションを思い付きました:

ディレクトリの主なアーキテクチャは次のとおりです。

main.py

setup.py

---problem_set_02/

------__init__.py

------p01.py

------p02.py

------p03.py

次に書き込みます__init__.py

from .p_02_paying_debt_off_in_a_year import compute_balance_after

ここ__main____init__、それは正確にモジュールを指しますproblem_set_02

次に行きmain.pyます:

import problem_set_02

setup.py特定のモジュールを環境に追加するためにを書くこともできます。



2

ディレクトリとサブディレクトリを作成した場合は、以下の手順に従ってください。すべてのディレクトリがディレクトリ__init__.pyとして認識されるようにする必要があることに注意してください 。

  1. スクリプトにとを含めるimport syssys.path、Pythonで使用可能なすべてのパスを確認できます。現在の作業ディレクトリを確認できる必要があります。

  2. ここで、使用したいサブディレクトリとそれぞれのモジュールをインポートimport subdir.subdir.modulename as abcします。これで、そのモジュールのメソッドを使用できます。

ここに画像の説明を入力してください

例として、このスクリーンショットでは、1つの親ディレクトリと2つのサブディレクトリがあり、2番目のサブディレクトリの下にモジュールがありますCommonFunction。右側のコンソールには、を実行した後sys.path、自分の作業ディレクトリが表示されます。


1

ドットを削除して、ファイルの先頭にabsolute_importをインポートします

from __future__ import absolute_import

from p_02_paying_debt_off_in_a_year import compute_balance_after

1

.pyファイルがあるメインフォルダーの名前を使用するだけです。

from problem_set_02.p_02_paying_debt_off_in_a_year import compute_balance_after
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.