[python] Python : 프로젝트 계층 구조의 동일한 수준에있는 다른 디렉터리에서 모듈 가져 오기

모든 종류의 예와 기타 유사한 질문을 보았지만 내 시나리오와 정확히 일치하는 예를 찾을 수없는 것 같습니다. 비슷한 질문이 너무 많기 때문에이 질문을하는 사람처럼 느껴지지만 “올바르게”작동하지 않는 것 같습니다. 내 프로젝트는 다음과 같습니다.

user_management  (package)
        |
        |------- __init__.py
        |
        |------- Modules/
        |           |
        |           |----- __init__.py
        |           |----- LDAPManager.py
        |           |----- PasswordManager.py
        |
        |------- Scripts/
        |           |
        |           |----- __init__.py
        |           |----- CreateUser.py
        |           |----- FindUser.py

“CreateUser.py”를 기본 user_management 디렉토리로 이동하면 쉽게 사용할 수 있습니다. "import Modules.LDAPManager"to import LDAPManager.py — 작동합니다. 내가 할 수없는 일은 (내가 원하는) Scripts 하위 폴더에 CreateUser.py를 유지하고 LDAPManager.py를 가져 오는 것입니다. 나는 이것을 사용하여 이것을 달성하기를 바랐다 "import user_management.Modules.LDAPManager.py". 이것은 작동하지 않습니다. 간단히 말해, Python 파일을 계층 구조에서 쉽게 더 깊게 볼 수 있지만 한 디렉터리를 위로 참조하고 다른 디렉터리로 아래로 참조하는 Python 스크립트를 가져올 수는 없습니다.

다음을 사용하여 내 문제를 해결할 수 있습니다.

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import Modules.LDAPManager as LDAPManager

나는 이것이 나쁜 습관이라고 들었고 낙담했습니다.

Scripts의 파일은 직접 실행되도록되어 있습니다 ( Scripts 의 init .py가 필요합니까?). 이 경우 -m 플래그로 CreateUser.py를 실행해야한다는 것을 읽었습니다. 나는 이것에 대한 몇 가지 변형을 시도했지만 CreateUser.py가 LDAPManager.py를 인식하도록 할 수 없습니다.



답변

CreateUser.py기본 user_management 디렉토리 로 이동 하면 쉽게 사용할 수 있습니다. import Modules.LDAPManagerto import LDAPManager.py
— 작동합니다.

제발 하지 마십시오 . 이런 식으로에서 LDAPManager사용 하는 모듈 CreateUser은 다른 가져 오기를 통해 가져온 모듈 과 동일 하지 않습니다 . 모듈에 전역 상태가 있거나 산세 / 산세 제거 중에 문제가 발생할 수 있습니다. 모듈이 동일한 디렉토리에 있기 때문에 작동하는 가져 오기를 피하십시오 .

패키지 구조가있는 경우 다음 중 하나를 수행해야합니다.

  • (가) 경우, 즉 상대적으로 수입 사용 CreateUser.pyScripts/:

     from ..Modules import LDAPManager
    

    이 점에 유의 했다 (메모 과거 시제)는 낙담 PEP 8 파이썬의 이전 버전은 잘 그들을 지원하지 않았다 때문하지만,이 문제는 년 전에 해결되었다. 전류 PEP 8 버전 않는 절대 수입으로 허용 가능한 대안들을 제시한다. 나는 실제로 패키지 내부를 좋아 합니다.

  • 절대 수입 사용하여 전체 패키지 이름을 사용하여가 ( CreateUser.pyScripts/) :

     from user_management.Modules import LDAPManager
    

두 번째 파일이 작동하려면 패키지 user_managementPYTHONPATH. 개발 중에 수동으로 호출을 추가 할 필요없이 IDE를 구성 할 수 sys.path.append있습니다.

또한 Scripts/하위 패키지가 이상하다는 것을 알았습니다 . 실제 설치에서 user_management모듈은 디렉토리 (OS에 라이브러리를 설치하는 데 사용되는 디렉토리) site-packages에있는 lib/디렉토리에 설치되지만 스크립트는 bin/디렉토리 (OS 용 실행 파일이 포함 된 디렉토리)에 설치되어야하기 때문 입니다.

사실 저는 믿습니다 Script/도 아래해서는 안됩니다 user_management. 같은 수준이어야합니다 user_management. 이러한 방법으로 당신이 할 수 없습니다 사용해야합니다 -m(이 다시, IDE를 구성 올바르게 패키지를 설치하거나 사용하는 문제입니다,하지만 당신은 단순히 확인 패키지를 찾을 수 있도록해야 PYTHONPATH=. python Scripts/CreateUser.py올바른 경로로 스크립트를 실행).


요약하면 내가 사용할 계층 구조 는 다음과 같습니다.

user_management  (package)
        |
        |------- __init__.py
        |
        |------- Modules/
        |           |
        |           |----- __init__.py
        |           |----- LDAPManager.py
        |           |----- PasswordManager.py
        |

 Scripts/  (*not* a package)
        |
        |----- CreateUser.py
        |----- FindUser.py

그런 다음 CreateUser.py및 의 코드는 FindUser.py절대 가져 오기를 사용하여 모듈을 가져와야합니다.

from user_management.Modules import LDAPManager

설치하는 동안 모듈을 찾을 수 있도록 실행 파일에 대한 디렉토리 내의 스크립트 및 user_management에서 끝날지 확인하십시오 PYTHONPATH. 개발 중에 IDE 구성에 의존하거나 상위 디렉토리를 다음에 CreateUser.py추가하기 시작 Scripts/합니다 PYTHONPATH( user_management및을 모두 포함하는 디렉토리를 의미 함 Scripts).

PYTHONPATH=/the/parent/directory python Scripts/CreateUser.py

또는 PYTHONPATH매번 지정할 필요가 없도록 전역 적으로 수정할 수 있습니다 . 유닉스 OS (Linux, Mac OS X 등)에서는 쉘 스크립트 중 하나를 수정하여 PYTHONPATH외부 변수 를 정의 할 수 있습니다. Windows에서는 환경 변수 설정을 변경해야합니다.


부록 필자는 python2를 사용하는 경우 다음을 입력하여 암시 적 상대 가져 오기를 피하는 것이 좋습니다.

from __future__ import absolute_import

모듈 상단에 있습니다. 이 방법은 import X 항상 최상위 모듈 을 가져 오는 것을 의미 하며 동일한 디렉토리에있는 파일 X을 가져 오려고 X.py하지 않습니다 (해당 디렉토리가에없는 경우 PYTHONPATH). 이런 식 으로 상대 가져 오기를 수행하는 유일한 방법은 명시 적 구문 (the from . import X)을 사용하는 것입니다. 이는 더 좋습니다 ( explicit is better than implicit ).

이렇게하면 “가짜”암시 적 상대 가져 오기를 사용하지 않도록 할 수 있습니다 ImportError. 이는 무언가 잘못되었다는 분명한 신호를 발생시키기 때문 입니다. 그렇지 않으면 생각과 다른 모듈을 사용할 수 있습니다.


답변

Python 2.5 이상에서는 다음을 사용할 수 있습니다.

from ..Modules import LDAPManager

선행 기간은 계층 구조에서 한 단계 “상승”합니다.

가져 오기에 대한 패키지 내 참조에 대한 Python 문서를 참조하세요 .


답변

“루트”에서 __init__.py당신은 또한 할 수 있습니다

import sys
sys.path.insert(1, '.')

두 모듈을 모두 가져올 수 있어야합니다.


답변