web-dev-qa-db-ja.com

相対インポート - ModuleNotFoundError:xという名前のモジュールはありません

私が本当に座ってpython 3を試してみたのはこれが初めてです。次の2つのファイルがあります。

  1. test.py
  2. config.py

config.pyには、いくつかの関数といくつかの変数が定義されています。私は次のようにそれを取り除きました:

enter image description here

ただし、次のようなエラーが表示されます。

ModuleNotFoundError: No module named 'config'

私はpy3の慣習は絶対インポートを使うことであることを知っています:

from . import config

ただし、これにより次のエラーが発生します。

ImportError: cannot import name 'config'

だからここで何をすればいいのか迷っています...どんな助けでも大歓迎です。 :)

65
Ryan

元の記事へのコメントで述べたように、これは私が何らかの理由で使っていたpythonインタプリタの問題であり、pythonスクリプトの問題ではないようです。私はWinPythonのバンドルからpython.orgの公式のpython 3.6に切り替えましたが、それはうまくいきました。みんなの助けてくれてありがとう:)

0
Ryan

TL; DR:__main__モジュールはパッケージの一部ではないので、あなたが自分のファイル{実行から相対インポートを行うことはできません。

絶対インポート - sys.pathで利用可能なものをインポートする

相対インポート - 現在のモジュールに相対的なものをインポートします。パッケージの一部でなければなりません

両方の亜種をまったく同じ方法で実行している場合は、どちらか一方が機能するはずです。とにかく、これは何が起こっているのか理解するのに役立つはずの例です。このような全体的なディレクトリ構造を持つ別のmain.pyファイルを追加しましょう:

.
./main.py
./ryan/__init__.py
./ryan/config.py
./ryan/test.py

そして何が起こっているのかを見るためにtest.pyを更新しましょう:

# 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を実行しましょう。

$ python ryan/test.py
__main__
Relative import failed
True

ここで "test"__main__モジュールで、パッケージに所属することについては何も知りません。ただし、ryanフォルダがsys.pathに追加されるため、import configは機能します。

代わりにmain.pyを実行しましょう。

$ python main.py
ryan.test
True
Absolute import failed

そしてここでテストは "ryan"パッケージの中にあり、相対インポートを実行できます。暗黙の相対インポートはPython 3では許可されていないため、import configは失敗します。

これが役に立ったことを願っています。

P.S .:もしあなたがPython 3を使い続けているのであれば、__init__.pyファイルにこれ以上の必要はありません。

84
Igonato

私はそれを考え出した。特にpython2から来る、非常にイライラする。

相対か絶対かにかかわらず、モジュールに.を追加する必要があります。

私は以下のようにディレクトリ設定を作成しました。

/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)

main.py

from lib import mody

mody.loaded()

mainを実行すると、これが起こります。

$ 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'

私は2to3を実行しました、そしてコア出力はこれでした

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

私はそれを修正するためにmody.pyのimport文を修正しなければなりませんでした

try:
    from modx import does_something
except ImportError:
    from .modx import does_something


def loaded():
    string = does_something()
    print(string)

それから私は再びmain.pyを走らせて期待した出力を得ました

$ python main.py
I gave you this string.

最後に、クリーンアップして2から3の間で移植できるようにします。

from __future__ import absolute_import
from .modx import does_something
34
user3159377

PYTHONPATHを設定してもこの問題を解決することができます。

これはWindows上でできることです。

set PYTHONPATH=.

17
Santosh Pillai

あなたの例を試してみました

from . import config

次のSystemErrorを受け取りました:
/usr/bin/python3.4 test.py
トレースバック(直近の呼び出しが最後):
ファイル "test.py"、1行目、
からインポート設定
SystemError:親モジュール ''がロードされていません。相対インポートを実行できません


これは私のために働くでしょう:

import config
print('debug=%s'%config.debug)

>>>debug=True

Pythonでテスト済み:3.4.2 - PyCharm 2016.3.2


この横にあるPyCharmはあなたに この名前のインポート を提供しています。
configをクリックするとヘルプアイコンが表示されます。 enter image description here

9
stovfl

モジュールのパスをPYTHONPATHに追加する必要があります。

export PYTHONPATH="${PYTHONPATH}:/path/to/your/module/"
5

この例はPython 3.6で動作します。

私はPyCharmでRun -> Edit Configurationsに行き、そこにあるすべてのエントリを削除し、そして再びPyCharmを通してコードを実行しようと試みることを勧めます。

それでもうまくいかない場合は、プロジェクトのインタプリタを確認し([設定] - > [プロジェクトインタプリタ])、設定のデフォルトを実行します([実行] - > [設定の編集]を選択)。

2
Carson Crane

次のファイルをテストディレクトリに追加するだけで、pythonがテストの前にそれを実行します。

__init__.py file

import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
1
Vinod Rane

Moduleを呼び出す前に、正しい sys.path listを宣言してください。

import os, sys

#'/home/user/example/parent/child'
current_path = os.path.abspath('.')

#'/home/user/example/parent'
parent_path = os.path.dirname(current_path)

sys.path.append(parent_path)
os.environ.setdefault('Django_SETTINGS_MODULE', 'child.settings')
0
HoangYell