Python의 상대 경로에서 가져 오기


답변:


142

2014 년 11 월 수정 (3 년 후) :

Python 2.6 및 3.x는 적절한 상대 가져 오기를 지원하므로 해킹을 피할 수 있습니다. 이 방법을 사용 하면 절대 가져 오기가 아닌 상대 가져 오기를 받고 있음을 알 수 있습니다 . '..'는 내 위에있는 디렉토리로 이동한다는 의미입니다.

from ..Common import Common

주의 사항으로, 이것은 패키지 외부 에서 Python을 모듈로 실행하는 경우에만 작동 합니다. 예를 들면 :

python -m Proj

원래 해키 방식

이 방법은 실제로 패키지를 '설치'하지 않는 일부 상황에서 여전히 일반적으로 사용됩니다. 예를 들어 Django 사용자에게 인기가 있습니다.

Common /을 sys.path에 추가 할 수 있습니다 (파이썬이 가져 오기 위해 보는 경로 목록) :

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

os.path.dirname(__file__) 현재 파이썬 파일이있는 디렉토리를 제공하고 디렉토리 'Common /'으로 이동하여 모듈을 'Common'으로 가져옵니다.


2
파이썬 모듈 경로를 수동으로 수정하지 마십시오. 빠른 해킹에만 해당 될 수 있습니다. distutils, setuptools 등을 사용하여 Python 패키지 관리를 배우는 것은 일반적으로 이와 같은 문제를 해결하는 데 필요한 기술입니다.
Sascha Gottfried 2014

1
@SaschaGottfried는 전적으로 동의하지만 배포 가능한 패키지를 만들지 않는다면 아마도 중요하지 않을 것입니다. 예를 들어, Django에서는 distutils로 앱을 실제로 설치하지 않으므로 위의 방법은 쉬운 해킹입니다. 그러나 어쨌든 나는 요즘 내가 할 일로 대답을 편집했습니다.
Dave

33
적절한 기술에 대한 설교 대신 실제 질문에 답 해주셔서 감사합니다. 상대적 수입을해야하는 많은 이유가 있습니다.
shrewmouse

한 단계 이상 올라가는 방법은 무엇입니까?
jxramos

10
한 단계 더 올라가려면 각 단계에 추가 점을 사용합니다. @jxramos 예 : from ...myfile이동../../myfile
WattsInABox

10

재밌고 방금 만난 동일한 문제였으며 다음과 같은 방식으로이 작업을 수행합니다.

linux 명령과 결합 ln하면 훨씬 간단하게 만들 수 있습니다.

1. cd Proj/Client
2. ln -s ../Common ./

3. cd Proj/Server
4. ln -s ../Common ./

이제 some_stufffile :에서 file : Proj/Common/Common.py로 가져 오려면 다음 Proj/Client/Client.py과 같이하십시오.

# in Proj/Client/Client.py
from Common.Common import some_stuff

그리고, 같은가 적용 Proj/Server또한 작동, setup.py공정, 동일 질문은 여기서 논의 , 그것은 도움이되기를 바랍니다!


10

상대 가져 오기를하지 마십시오.

에서 PEP8 :

패키지 내 수입에 대한 상대적 수입은 매우 권장되지 않습니다.

모든 코드를 하나의 슈퍼 패키지 (예 : "myapp")에 넣고 클라이언트, 서버 및 공통 코드에 대한 하위 패키지를 사용합니다.

업데이트 : " Python 2.6 및 3.x는 적절한 상대 가져 오기를 지원합니다 (...) ". 자세한 내용은 Dave의 답변 을 참조하십시오.


1
' if __name__ == "__main__":'줄 뒤의 클라이언트와 서버 끝에 몇 가지 코드를 추가한다고 상상해보십시오 . 즉, 독립 실행 형 스크립트로 사용할 수 있기를 원합니다. 제대로하는 방법? 지원해야 할 완벽하게 일반적인 사용 사례라고 생각합니다. 왜 낙담합니까?
Jabba

83
내가 "하지 마"라는 놀라게하고 대한 허용 대답은 "어떻게 ... 어떻게"질문 (레일 <g>을 제외하고 잘,.)이 있습니다 이 작업을 수행하는 가끔 이유. Dave가 제안한 것과 유사한 솔루션을 사용합니다.
Tom Wilson

1
@TomWilson : 순수한 "하지 마세요"대답이 아닙니다. 아래에 "이 방법으로하기"가 있습니다.
Michał Šrajer

2
누군가 Numpy에서 사람들에게 말해야합니다! 그들은 상대적 수입의 TON을 사용합니다!
Austin A

12
이 답변은 현재 버전의 Python에는 적용되지 않습니다. 인용 된 부분은 더 이상 PEP 8에서 찾을 수 없습니다. 요즘에는 "명시 적 상대 가져 오기는 절대 가져 오기에 대한 허용 가능한 대안입니다. 특히 절대 가져 오기를 사용하는 것이 불필요하게 장황한 복잡한 패키지 레이아웃을 다룰 때"
moooeeeep

8

상대 수입을하는 것은 절대적으로 OK! 내가하는 일은 다음과 같습니다.

#first change the cwd to the script path
scriptPath = os.path.realpath(os.path.dirname(sys.argv[0]))
os.chdir(scriptPath)

#append the relative location you want to import from
sys.path.append("../common")

#import your module stored in '../common'
import common.py

1
그러나 sys.argv [0]이 실제로 가리키는 위치를 더 잘 알 수 있습니다. (아마도) 파이썬을 시작할 때 있던 디렉토리가 아닙니다.
CarlH

이것은 많은 함정이있는 빠른 해킹입니다. 그러나 질문은 더 나아지지 않았습니다.
Sascha Gottfried 2014

1
이 명확하게 작성하지만, 원래 해킹 데이브의 대답은 그것을 사용하기 때문에 더 나은 __file__현재 파일에서 적절한 관계를 얻을 수
존 노이 하우스

4

기본 가져 오기 방법은 PYTHONPATH에서 이미 "상대적"입니다. PYTHONPATH는 기본적으로 원본 소스 파일의 폴더와 함께 일부 시스템 라이브러리에 있습니다. -m을 사용하여 모듈을 실행하면 현재 디렉토리가 PYTHONPATH에 추가됩니다. 따라서 프로그램의 진입 점이 Proj 내부에 있으면 사용 import Common.Common은 Server.py와 Client.py 모두에서 작동합니다.

상대적 가져 오기를하지 마십시오. 원하는대로 작동하지 않습니다.


1
이것이 사실이라면 왜 상위 답변이 이것을 말하지 않습니까? 이것이 작동할까요?
Anonymous
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.