모든 종류의 예와 기타 유사한 질문을 보았지만 내 시나리오와 정확히 일치하는 예를 찾을 수없는 것 같습니다. 비슷한 질문이 너무 많기 때문에이 질문을하는 사람처럼 느껴지지만 “올바르게”작동하지 않는 것 같습니다. 내 프로젝트는 다음과 같습니다.
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.LDAPManager
to importLDAPManager.py
— 작동합니다.
제발 하지 마십시오 . 이런 식으로에서 LDAPManager
사용 하는 모듈 CreateUser
은 다른 가져 오기를 통해 가져온 모듈 과 동일 하지 않습니다 . 모듈에 전역 상태가 있거나 산세 / 산세 제거 중에 문제가 발생할 수 있습니다. 모듈이 동일한 디렉토리에 있기 때문에 작동하는 가져 오기를 피하십시오 .
패키지 구조가있는 경우 다음 중 하나를 수행해야합니다.
-
(가) 경우, 즉 상대적으로 수입 사용
CreateUser.py
에Scripts/
:from ..Modules import LDAPManager
이 점에 유의 했다 (메모 과거 시제)는 낙담 PEP 8 파이썬의 이전 버전은 잘 그들을 지원하지 않았다 때문하지만,이 문제는 년 전에 해결되었다. 전류 PEP 8 버전 않는 절대 수입으로 허용 가능한 대안들을 제시한다. 나는 실제로 패키지 내부를 좋아 합니다.
-
절대 수입 사용하여 전체 패키지 이름을 사용하여가 (
CreateUser.py
에Scripts/
) :from user_management.Modules import LDAPManager
두 번째 파일이 작동하려면 패키지 user_management
가 PYTHONPATH
. 개발 중에 수동으로 호출을 추가 할 필요없이 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, '.')
두 모듈을 모두 가져올 수 있어야합니다.