TL; DR :
Python 3.3에서는 아무것도 할 필요가 없으며 __init__.py네임 스페이스 패키지 디렉토리에 아무 것도 넣지 않아도 됩니다. 3.3 이전 버전에서는 미래에 대비하고 이미 암시 적 네임 스페이스 패키지와 호환되므로 pkgutil.extend_path()솔루션을 선택하십시오 pkg_resources.declare_namespace().
Python 3.3에는 암시 적 네임 스페이스 패키지가 도입되었습니다 ( PEP 420 참조) .
이것은 이제 다음으로 만들 수있는 세 가지 유형의 객체가 있음을 의미합니다 import foo.
foo.py파일로 표현되는 모듈
- 파일을
foo포함하는 디렉토리로 표시되는 일반 패키지__init__.py
- 파일이
foo없는 하나 이상의 디렉토리로 표시되는 네임 스페이스 패키지__init__.py
패키지도 모듈이지만 여기서는 "모듈"이라고 말할 때 "비 패키지 모듈"을 의미합니다.
먼저 sys.path모듈 또는 일반 패키지를 검색 합니다. 성공하면 검색을 중지하고 모듈 또는 패키지를 생성하고 초기화합니다. 모듈이나 일반 패키지를 찾지 못했지만 하나 이상의 디렉토리를 찾은 경우 네임 스페이스 패키지를 만들고 초기화합니다.
모듈 및 일반 패키지 가 작성된 파일로 __file__설정되었습니다 .py. 일반 및 네임 스페이스 패키지 __path__가 작성된 디렉토리로 설정되었습니다.
그렇게 import foo.bar하면 위의 검색이 먼저 수행 된 foo다음 패키지가 발견되면 검색 bar이 foo.__path__대신 검색 경로로 수행됩니다 sys.path. 경우 foo.bar발견, foo그리고 foo.bar생성 및 초기화된다.
그렇다면 일반 패키지와 네임 스페이스 패키지는 어떻게 혼합됩니까? 일반적으로 그렇지는 않지만 기존 pkgutil명시 적 네임 스페이스 패키지 메서드는 암시 적 네임 스페이스 패키지를 포함하도록 확장되었습니다.
다음과 같은 기존 일반 패키지가있는 __init__.py경우 :
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
... 레거시 동작은 검색된 경로에 다른 일반 패키지 를 추가하는 것 __path__입니다. 그러나 Python 3.3에서는 네임 스페이스 패키지도 추가합니다.
따라서 다음 디렉토리 구조를 가질 수 있습니다.
├── path1
│ └── package
│ ├── __init__.py
│ └── foo.py
├── path2
│ └── package
│ └── bar.py
└── path3
└── package
├── __init__.py
└── baz.py
... 그리고 한 두로 __init__.py이 extend_path줄을 (그리고 path1, path2그리고 path3당신에있는 sys.path) import package.foo, import package.bar그리고 import package.baz모든 작업은 것이다.
pkg_resources.declare_namespace(__name__) 암시 적 네임 스페이스 패키지를 포함하도록 업데이트되지 않았습니다.