이 디렉토리 구조를 상상해보십시오.
app/
__init__.py
sub1/
__init__.py
mod1.py
sub2/
__init__.py
mod2.py
코딩 mod1
중이며에서 무언가를 가져와야합니다 mod2
. 어떻게해야합니까?
시도 from ..sub2 import mod2
했지만 “비 패키지로 시도한 상대 가져 오기”가 표시됩니다.
나는 주변을 봤지만 ” sys.path
조작”해킹 만 발견했다 . 깨끗한 방법이 없습니까?
편집 : 내 모든 __init__.py
것이 현재 비어 있습니다
Edit2 : sub2에는 하위 패키지 ( , 등) sub1
에서 공유되는 클래스가 포함되어 있기 때문에이 작업을 수행하려고합니다 subX
.
편집 3 : 내가 찾고있는 행동은 PEP 366에 설명 된 것과 동일합니다 (John B에게 감사합니다)
답변
모든 사람들이 질문에 대답하기보다는 무엇을해야하는지 말하고 싶은 것 같습니다.
문제는 mod1.py를 인터프리터에 인수로 전달하여 모듈을 ‘__main__’로 실행한다는 것입니다.
에서 PEP 328 :
상대적 가져 오기는 모듈의 __name__ 속성을 사용하여 패키지 계층에서 해당 모듈의 위치를 결정합니다. 모듈 이름에 패키지 정보가 포함되어 있지 않은 경우 (예 : ‘__main__’로 설정) 모듈이 실제로 파일 시스템의 위치에 상관없이 모듈이 최상위 모듈 인 것처럼 상대 가져 오기가 해결됩니다.
Python 2.6에서는 기본 모듈을 기준으로 모듈을 참조하는 기능이 추가되었습니다. PEP 366 은 변경 사항을 설명합니다.
업데이트 : Nick Coghlan에 따르면 권장되는 대안은 -m 스위치를 사용하여 패키지 내에서 모듈을 실행하는 것입니다.
답변
나를 위해 일하는 해결책은 다음과 같습니다.
상대 가져 오기 from ..sub2 import mod2
를 수행 mod1.py
한 다음 실행 하려면 부모 디렉토리로 이동 app
하여 python -m 스위치를 사용하여 모듈을 실행하십시오 python -m app.sub1.mod1
.
이 문제가 상대적 가져 오기에서 발생하는 실제 이유 __name__
는 모듈 의 속성을 가져 와서 상대적 가져 오기가 작동하기 때문 입니다. 모듈이 직접 실행중인 경우 __name__
로 설정되며 __main__
패키지 구조에 대한 정보가 포함되어 있지 않습니다. 그리고 그것이 파이썬이 relative import in non-package
오류 에 대해 불평하는 이유 입니다.
따라서 -m 스위치를 사용하면 패키지 구조 정보를 파이썬에 제공하여 관련 가져 오기를 성공적으로 해결할 수 있습니다.
상대 가져 오기를 수행하는 동안이 문제가 여러 번 발생했습니다. 그리고 이전의 모든 대답을 읽은 후에도 모든 파일에 상용구 코드를 넣지 않고도 깨끗하게 해결하는 방법을 알 수 없었습니다. (@ncoghlan 및 @XiongChiamiov 덕분에 일부 의견이 실제로 도움이되었지만)
PEP를 통과하는 것이 실제로 재미 있지 않기 때문에 상대 수입 문제로 싸우는 사람에게 도움이되기를 바랍니다.
답변
main.py
setup.py
app/ ->
__init__.py
package_a/ ->
__init__.py
module_a.py
package_b/ ->
__init__.py
module_b.py
- 당신은 실행합니다
python main.py
. main.py
않습니다 :import app.package_a.module_a
module_a.py
않습니다import app.package_b.module_b
또는 2 또는 3은 다음을 사용할 수 있습니다. from app.package_a import module_a
그것은 당신이 app
당신의 PYTHONPATH에 있는 한 작동합니다. main.py
그때 어디에나있을 수 있습니다.
따라서 setup.py
전체 앱 패키지 및 하위 패키지를 대상 시스템의 python 폴더 및 main.py
대상 시스템의 스크립트 폴더 에 복사 (설치)하기 위해 a 를 작성합니다 .
답변
“Guido는 패키지 내에서 스크립트를 실행하는 것을 안티 패턴으로 간주합니다”( PEP-3122 거부
)
솔루션을 찾기 위해 많은 시간을 보냈습니다. 스택 오버플로에서 관련 게시물을 읽고 나에게 “더 나은 방법이 있어야합니다!”라고 말합니다. 없는 것 같습니다.
답변
이것은 100 % 해결됩니다 :
- 앱/
- main.py
- 설정 /
- local_setings.py
app / main.py에서 settings / local_setting.py 가져 오기 :
main.py :
import sys
sys.path.insert(0, "../settings")
try:
from local_settings import *
except ImportError:
print('No Import')
답변
def import_path(fullpath):
"""
Import a file with full path specification. Allows one to
import from anywhere, something __import__ does not do.
"""
path, filename = os.path.split(fullpath)
filename, ext = os.path.splitext(filename)
sys.path.append(path)
module = __import__(filename)
reload(module) # Might be out of date
del sys.path[-1]
return module
이 스 니펫을 사용하여 경로에서 모듈을 가져옵니다.
답변
nosklo's
예를 들어 대답에 대한 설명
참고 : 모든 __init__.py
파일이 비어 있습니다.
main.py
app/ ->
__init__.py
package_a/ ->
__init__.py
fun_a.py
package_b/ ->
__init__.py
fun_b.py
app / package_a / fun_a.py
def print_a():
print 'This is a function in dir package_a'
app / package_b / fun_b.py
from app.package_a.fun_a import print_a
def print_b():
print 'This is a function in dir package_b'
print 'going to call a function in dir package_a'
print '-'*30
print_a()
main.py
from app.package_b import fun_b
fun_b.print_b()
실행하면 다음 $ python main.py
을 반환합니다.
This is a function in dir package_b
going to call a function in dir package_a
------------------------------
This is a function in dir package_a
- main.py는 다음을 수행합니다.
from app.package_b import fun_b
- fun_b.py는
from app.package_a.fun_a import print_a
그래서 폴더의 package_b
파일은 package_a
원하는 폴더의 파일을 사용했습니다 . 권리??