2011-01-11 5 views
22
stuff/ 
    __init__.py 
    mylib.py 
    Foo/ 
     __init__.py 
     main.py 
     foo/ 
      __init__.py 
      script.py 

script.py이 그냥 예입니다 mylib.py파이썬에서 상대적으로 가져 오기를 수행하는 방법을

가져 싶어하지만 정말 난 그냥 상위 디렉토리에 모듈의 상대 가져 오기를 수행합니다. 나는

Attempted relative import beyond toplevel package

가 어디 선가 읽고 ... 여러 가지를 시도하고이 오류가 한 그 프로그램이없는 패키지에해야 시작하고, 내가 지금처럼 그의 구조를 수정 시도 곳에서 스크립트 ...

stuff/ 
    mylib.py 
    foo.py // equivalent of main.py in above 
    foo/ 
     __init__.py 
     script.py 

하지만 같은 오류가 발생했습니다.

어떻게하면됩니까? 이것도 적절한 접근 방법입니까?

편집 : 파이썬 2에서

답변

28

로 가져 오는 것입니다, 나는 그것을 설정하고 내가 foo는 사용하지 않습니다 특이성을 위해 방법을 실현 바 이름. 내 프로젝트 디렉토리가 ...로 설정

tools/ 
    core/ 
     object_editor/ 
      # files that need to use ntlib.py 
      editor.py # see example at bottom 
      __init__.py 
     state_editor/ 
      # files that need to use ntlib.py 
      __init__.py 
     ntlib.py 
     __init__.py # core is the top level package 
    LICENSE 
    state_editor.py # equivalent to main.py for the state editor 
    object_editor.py # equivalent to main.py for the object editor 

object_editor.py에 선 모습

...
from core.object_editor import editor 

editor.py에 선 모습

...

from .. import ntlib 

또는 택일 적으로

from core import ntlib 

핵심은 내가 질문에서 준 예제에서 "main"스크립트가 패키지 내에서 실행되고 있다는 것입니다. 일단 그것을 옮기고 특정 패키지 (core)를 만들고 편집자가 그 패키지에 (ntlib)를 공유하기를 원하는 라이브러리를 옮기면 모든 것이 늠름한 것입니다.

+1

당신이 가지고 있습니다. 무슨 일이 벌어지고 있는가를 명령 줄에서 실행중인 스크립트에서 상대적인 가져 오기를 사용할 수 없다는 것입니다. 따라서 아래의 항목을 참조하여 조직의 최상위 레벨에 있어야합니다. –

+0

패키지에서 "main"스크립트가 실행되는 이유는 무엇입니까? – Bin

1

import ..foo..stuff.mylib가 확인을해야

편집은 확장을했다

한 "물건"당신의 파이썬 경로에 아니지만 당신이 경로를 추가하는 대신 선택의 여지가 없어
+4

나는 이것이 올바른 구문입니다 생각하지 않습니다. – random

+0

'from ..foo..stuff.mylib import whatever'는 괜찮습니다. – tekknolagi

+0

import sys sys.path.append() import Bar
tekknolagi

10

.

당신은 당신이 예를 위해 할 수있는 것들로부터 script.py의 수준을 알고있는 경우 : 당신이 포장되지 않은 파일을 가져 상대 가져 오기를 사용할 수 없다는 표시 PEP에서

import sys 
import os 
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) 
+9

여기에 문서가 있습니까? 나는 당신을 믿지 않지만, 단지 "2 개의 디렉토리에서 가져 오기"라고 말하고 싶다면 시스템 경로를 수정해야한다. 나는 내 눈으로 그것을보아야한다. – random

+0

이것은 내가 어쩔 줄 몰라서 보통 내가하고있는 일이다. – jdm

+0

정확히 그처럼 문서화 된 것은 아닙니다. 나는이 여러 번 나 자신을 사용했지만. 어쨌든 시스템에서 전역 적으로 실행되는 python 스크립트의 시스템 경로를 수정합니다. 나는 네가 신경 쓸 필요가 없다고 생각한다. : P –

1

합니다.

그래서 당신은 그러나 from .mylib import *

처럼 뭔가에 수입 물건에 __init__.py를 추가하고 변경해야는 PEP는 모듈에서 패키지 MYLIB을 유지 할 허용하지 않습니다 보인다. 따라서 라이브러리 함수를 호출하는 방법을 변경해야 할 수도 있습니다.

또 다른 대안은 서브 패키지로 MYLIB를 이동하고 조금 더 그것을 만지작 후 from .libpackage import mylib

7

필자는 Windows 7에서 Python 3.4.2를 실행 중이며이를 사용하고 있습니다.

다음 중 하나를 실행하는 경우 :

파이썬 -m 유닛 테스트 파이썬 -m 유닛 테스트는

... 나는 것 '최상위 패키지 넘어 시도 상대 가져 오기'를 얻을 오류를 발견 할 수 있습니다.

나를 위해, 솔루션은 내 [test_stock.py]에 ".."를 떨어 뜨리고있었습니다. ..stock 가져 오기 재고에서

에 변경 : 라인이었다 재고 가져 오기 재고

에서 .. 그것은 작동합니다.

폴더 구조 :

C:\ 
    | 
    +-- stock_alerter 
      | 
      +-- __init__.py 
      +-- stock.py 
      | 
      \-- tests 
        | 
        +-- __init__.py 
        \-- test_stock.py 
+0

당신의 솔루션은 작동하지만 왜 필자는 이해할 수 없습니다 ... 또한, Pycharm은 이것으로 미친 듯이 보입니다. –

+0

그것은'..'을 제거 할 때 더 이상 상대적 임포트가 아니기 때문에 작동합니다. 대신 그것은 절대적인 수입입니다. PyCharm은 프로젝트의 소스 디렉토리를 사용하여이를 해결합니다. 즉, 프로젝트 설정에서 디렉토리를 수동으로 추가해야 수입을 해결할 수 있습니다. – meowsqueak

관련 문제