상대 가져 오기-ModuleNotFoundError : x라는 모듈이 없습니다.


178

이것은 내가 실제로 앉아서 Python 3을 사용해 보았을 때 처음으로 실패한 것처럼 보입니다. 다음 두 파일이 있습니다.

  1. test.py
  2. config.py

config.py에는 몇 가지 변수와 함께 몇 가지 함수가 정의되어 있습니다. 나는 그것을 다음과 같이 제거했다.

config.py

debug = True

test.py

import config
print (config.debug)

나는 또한 __init__.py

그러나 다음과 같은 오류가 발생합니다.

ModuleNotFoundError: No module named 'config'

py3 규칙은 절대 가져 오기를 사용한다는 것을 알고 있습니다.

from . import config

그러나 이로 인해 다음 오류가 발생합니다.

ImportError: cannot import name 'config'

그래서 나는 여기서 무엇을 해야할지에 대해 상실하고 있습니다 ... 어떤 도움이라도 대단히 감사합니다. :)


오류를 재현 할 수 없습니다.이 코드를 어떻게 실행합니까?
Copperfield

2
파이썬과 함께 제공되는 유휴 상태에서 실행하고로도 python test.py완벽하게 작동합니다. pyCharm은 없지만 문제를 일으키는 pyCharm의 잘못된 구성
Copperfield

1
매우 이상합니다. WinPython을 사용하고 있습니다-python.org에서 vanilla Python 3.6을 다운로드하면 정상적으로 작동합니다. 통역사를 확인하려고 생각하지 마십시오! 감사!
blitzmann

1
내 생각 엔 PYTHONPATH와 함께 펑키 한 무언가가 진행되고 있습니다. IDE 설정 및 / 또는 시스템 환경 변수를 확인하십시오.
Martin Tournoij

1
나는 똑같은 문제가 있습니다. pycharm이 아닙니다! python3입니다. 그것은 python2에서 작동하지만 python3을 사용할 때이 오류가 나타납니다! 매우 실망스러운.

답변:


163

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

여기에서 "시험" 이다__main__ 모듈과 패키지에 속하는 대해 아무것도 알지 못한다. 그러나 폴더가 sys.path에 추가 import config되므로 작동해야합니다 ryan.

대신 main.py를 실행하자 :

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

그리고 여기서 테스트는 "ryan"패키지 안에 있으며 상대적인 가져 오기를 수행 할 수 있습니다. import config암시 적 상대 가져 오기는 Python 3에서 허용되지 않으므로 실패합니다.

이것이 도움이 되었기를 바랍니다.

추신 : 파이썬 3을 고수하고 있다면 더 이상 __init__.py파일이 필요하지 않습니다 .


3
절대 수입품이 항상 작동하도록 할 수있는 일이 있습니까? 처럼, sys.path.append('/some/path/my_module')안에 전화 /some/path/my_module/__init__.py?
James T.

4
@JamesT. 예, sys.path런타임 중에 수정 하는 것이 일반적입니다 ( github.com/… ). PYTHONPATH 환경 변수를 설정할 수도 있습니다.
Igonato

6
"Python 3을 고수하고 있다면 더 이상 __init__.py파일이 필요하지 않습니다 ." 흥미 롭군 이것에 대해 자세히 설명해 주시겠습니까? 패키지 해상도 메커니즘이 2와 3 사이에서 크게 바뀌지 않았다는 인상을 받았습니다.
Kevin

2
"Python 3을 고수하고 있다면 더 이상 __init__.py파일이 필요하지 않습니다 ." 반대로 패키지가 2와 3 모두에서 작동하기를 원한다면 설명 할 수 있습니까? 그리고 비참하게 - 아웃 - 오브 - 날짜 2009 참조 무엇 인 __init__.py을 위해? 가장 많이 찬성 한 답변은 "패키지의 일부" 입니다. 우리는 구별 강조 시작해야 "[이전, 사전 3.3] 일반 패키지를""네임 스페이스 패키지 [3.3 이상]" 모든 곳에서 자주.
smci

61

나는 그것을 알아. 특히 python2에서 오는 매우 좌절.

.모듈이 상대인지 절대인지에 관계없이 모듈 에 a를 추가해야합니다 .

다음과 같이 디렉토리 설정을 작성했습니다.

/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

1
가치는 것을주의 try/except로딩 절차는 (어떤 사람들은 사용할 필요가 여기에 작동하는 실제 성분이다 try:scripts.modx하고 except: modx), 나를 위해이 문제를 해결 것이었다.
Justapigeon

40

PYTHONPATH를 설정하면이 문제에 도움이 될 수 있습니다.

Windows에서 수행하는 방법은 다음과 같습니다.

set PYTHONPATH=.


11
PYTHONPATH를 기본 코드 디렉토리로 설정하면 문제가 해결되었습니다!
Geek

1
Linux에서도 작동합니다. 수출 PYTHONPATH =.
rjdkolb

29

에 모듈 경로를 추가해야합니다 PYTHONPATH.


UNIX의 경우 (Linux, OSX, ...)

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

Windows의 경우

set PYTHONPATH=%PYTHONPATH%;C:\path\to\your\module\

4
감사합니다 @Giorgos! 도커 이미지에서 루트 디렉토리를 설정하려고 할 때 특히 그렇습니다.
Tony Fraser

15

모범을 보았습니다

from . import config

다음 SystemError가 발생했습니다.
/usr/bin/python3.4 test.py
Traceback (가장 최근 호출) :
"test.py"파일, 1 행
. import config
SystemError : 상위 모듈 ''이 (가)로드되지 않았습니다. 상대적 가져 오기를 수행 할 수 없습니다


이것은 나를 위해 작동합니다 :

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

>>>debug=True

Python으로 테스트 : 3.4.2-PyCharm 2016.3.2


이 PyCharm 옆에이 이름가져올 수 있습니다 .
를 클릭 config하면 도움말 아이콘이 나타납니다. 여기에 이미지 설명을 입력하십시오


11

테스트 디렉토리에 다음 파일을 추가하면 파이썬이 테스트 전에 파일을 실행합니다.

__init__.py file

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

이것이 바로 내가 찾던 것입니다. 이 답변을 공유해 주셔서 감사합니다 !!!
Mayur

이와 같은 작업을 수행하면 linter (pylint3) 오류가 발생합니다. 오류는이 오류와 비슷합니다. filename.py:12:0 : C0413 : 가져 오기 "import abc.def.ghi.file_util as file_util"을 모듈 맨 위에 놓아야합니다 (잘못된 가져 오기 위치)
Sharad

6

PYTHONPATH루트 프로젝트 디렉토리에서 환경 변수를 설정하십시오 .

유닉스 계열을 고려하면 :

export PYTHONPATH=.

4

이 예제는 Python 3.6에서 작동합니다.

Run -> Edit ConfigurationsPyCharm으로 이동하여 항목을 삭제하고 PyCharm을 통해 코드를 다시 실행하는 것이 좋습니다 .

그래도 작동하지 않으면 프로젝트 인터프리터 (설정-> 프로젝트 인터프리터)를 확인하고 구성 기본값 (실행-> 구성 편집 ...)을 실행하십시오.


4

모듈을 호출하기 전에 올바른 sys.path 목록을 선언하십시오 .

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

1

원래 게시물에 대한 의견에서 언급했듯이 이것은 파이썬 스크립트에 문제가 아닌 어떤 이유로 든 파이썬 인터프리터에 문제가있는 것 같습니다. python.org에서 WinPython 번들에서 공식 python 3.6으로 전환했으며 정상적으로 작동했습니다. 도움을 주셔서 감사합니다 모두 :)


1
흠이 말을 싫어하지만 같은 일이 저에게 일어났습니다. 환경을 다시 만들면 문제가 해결됩니다. 필자의 경우 테스트를 실행할 때이 오류가 발생했습니다. 동일한 환경에서 동일한 모듈을 가져 오려고 시도했습니다. 환경을
재생성

1
다른 IDE는 프로젝트 소스 파일 (보기, 모듈, 템플릿 등)에 대해 경로를 처리하는 다른 방법을 가지고 있습니다. 프로젝트가 올바르게 구성되고 코딩되면 모든 (표준) IDE에서 작동해야합니다. WinPython과 같이 널리 사용되는 IDE에 문제가 있다는 것은 실제로 프로젝트에서 문제가 발생했음을 의미합니다. 위에서 언급했듯이 문제는 user3159377의 "모듈에.을 추가해야합니다"라는 것입니다.
winux

1

파이썬 3 이상을 사용하는 경우 아래 줄을 추가하십시오.

import os, sys
dir_path = os.path.dirname(os.path.realpath(__file__))
parent_dir_path = os.path.abspath(os.path.join(dir_path, os.pardir))
sys.path.insert(0, parent_dir_path)

0

시험

from . import config

그 기능은 동일한 폴더 수준에서 가져 오는 것입니다. 직접 가져 오려고하면 종속 된 것으로 간주합니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.