IT박스

파이썬에서 네임 스페이스 패키지를 어떻게 만듭니 까?

itboxs 2020. 7. 1. 08:17
반응형

파이썬에서 네임 스페이스 패키지를 어떻게 만듭니 까?


Python에서 네임 스페이스 패키지를 사용하면 여러 프로젝트에 Python 코드를 배포 할 수 있습니다. 이 기능은 관련 라이브러리를 별도의 다운로드로 릴리스하려는 경우에 유용합니다. 예를 들어, 디렉토리와 Package-1Package-2에서 PYTHONPATH,

Package-1/namespace/__init__.py
Package-1/namespace/module1/__init__.py
Package-2/namespace/__init__.py
Package-2/namespace/module2/__init__.py

최종 사용자는 import namespace.module1import namespace.module2.

하나 이상의 Python 제품이 해당 네임 스페이스에서 모듈을 정의 할 수 있도록 네임 스페이스 패키지를 정의하는 가장 좋은 방법은 무엇입니까?


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다음 패키지가 발견되면 검색 barfoo.__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__.pyextend_path줄을 (그리고 path1, path2그리고 path3당신에있는 sys.path) import package.foo, import package.bar그리고import package.baz 모든 작업은 것이다.

pkg_resources.declare_namespace(__name__) 암시 적 네임 스페이스 패키지를 포함하도록 업데이트되지 않았습니다.


표준 모듈이 있는데 pkgutil 이 있습니다.이 모듈을 사용하면 지정된 네임 스페이스에 모듈을 '추가'할 수 있습니다.

제공 한 디렉토리 구조로 :

Package-1/namespace/__init__.py
Package-1/namespace/module1/__init__.py
Package-2/namespace/__init__.py
Package-2/namespace/module2/__init__.py

당신은 모두 그 두 줄 넣어야 Package-1/namespace/__init__.py하고 Package-2/namespace/__init__.py(*)를 :

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

(* since -unless you state a dependency between them- you don't know which of them will be recognized first - see PEP 420 for more information)

As the documentation says:

This will add to the package's __path__ all subdirectories of directories on sys.path named after the package.

From now on, you should be able to distribute those two packages independently.


This section should be pretty self-explanatory.

In short, put the namespace code in __init__.py, update setup.py to declare a namespace, and you are free to go.


This is an old question, but someone recently commented on my blog that my posting about namespace packages was still relevant, so thought I would link to it here as it provides a practical example of how to make it go:

https://web.archive.org/web/20150425043954/http://cdent.tumblr.com/post/216241761/python-namespace-packages-for-tiddlyweb

That links to this article for the main guts of what's going on:

http://www.siafoo.net/article/77#multiple-distributions-one-virtual-package

The __import__("pkg_resources").declare_namespace(__name__) trick is pretty much drives the management of plugins in TiddlyWeb and thus far seems to be working out.


You have your Python namespace concepts back to front, it is not possible in python to put packages into modules. Packages contain modules not the other way around.

A Python package is simply a folder containing a __init__.py file. A module is any other file in a package (or directly on the PYTHONPATH) that has a .py extension. So in your example you have two packages but no modules defined. If you consider that a package is a file system folder and a module is file then you see why packages contain modules and not the other way around.

So in your example assuming Package-1 and Package-2 are folders on the file system that you have put on the Python path you can have the following:

Package-1/
  namespace/
  __init__.py
  module1.py
Package-2/
  namespace/
  __init__.py
  module2.py

You now have one package namespace with two modules module1 and module2. and unless you have a good reason you should probably put the modules in the folder and have only that on the python path like below:

Package-1/
  namespace/
  __init__.py
  module1.py
  module2.py

참고URL : https://stackoverflow.com/questions/1675734/how-do-i-create-a-namespace-package-in-python

반응형