Python 3.3 이상에서 패키지에 __init__.py가 필요하지 않습니까?


195

Python 3.5.1을 사용하고 있습니다. https://docs.python.org/3/tutorial/modules.html#packages 에서 문서와 패키지 섹션을 읽었습니다.

이제 다음과 같은 구조가 있습니다.

/home/wujek/Playground/a/b/module.py

module.py:

class Foo:
    def __init__(self):
        print('initializing Foo')

이제는 /home/wujek/Playground:

~/Playground $ python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x100a8f0b8>

마찬가지로, 이제 집에서 다음과 Playground같은 슈퍼 폴더가 있습니다 :

~ $ PYTHONPATH=Playground python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x10a5fee10>

실제로 모든 종류의 작업을 수행 할 수 있습니다.

~ $ PYTHONPATH=Playground python3
>>> import a
>>> import a.b
>>> import Playground.a.b

왜 이것이 작동합니까? 내가있을 필요하지만 __init__.py모두에서 파일 (비어있는 작업 것) ab대한 module.py임포트 될 때까지 파이썬 경로 지점 Playground폴더?

이것은 파이썬 2.7에서 변경된 것으로 보입니다.

~ $ PYTHONPATH=Playground python
>>> import a
ImportError: No module named a
>>> import a.b
ImportError: No module named a.b
>>> import a.b.module
ImportError: No module named a.b.module

__init__.py둘 다 ~/Playground/a와 함께 ~/Playground/a/b잘 작동합니다.

답변:


192

Python 3.3+에는 파일 없이 패키지를 만들 수있는 암시 적 네임 스페이스 패키지__init__.py있습니다.

암시 적 네임 스페이스 패키지를 허용한다는 것은 __init__.py파일 제공 요구 사항 이 완전히 삭제 되어 영향을받을 수 있음 을 의미합니다 .

__init__.py파일을 사용 하는 오래된 방법은 여전히 Python 2에서 와 같이 작동합니다.


10
나는 문서를 읽을 것이지만 조금 길다. 빠르게 요약 할 수 있습니까? 그냥 말해 줄 수 있습니까 : 여전히 init .py를 지원 합니까, 아니면 완전히 무시합니까? 그것이 그들을 지원한다면, 기능의 차이점은 무엇이며 왜이 이중성이됩니까?
wujek

3
따라서 튜토리얼을 업데이트해야합니다. 문서 버그가 열렸습니까?
Michel Samia

4
나는 이것이 여전히 Zen Of Python 2 행을 무시한다고 화를 Explicit is better than implicit.
낸다

5
@JayRizzo 그러나 : "실용성은 순결을 능가합니다."
Mike Müller

19
@JayRizzo IMO 훨씬 더 명시 적입니다. 때로는 초기화 작업을 수행합니다.__init__.py 하지만 때로는 그렇지 않습니다. 파이썬 3에서는 이러한 것들이 필요할 때 __init__.py특정 코드 로 새로운 것을 만듭니다 . 그렇지 않으면 그렇지 않습니다. 이것은 어떤 패키지가 사용자 정의 초기화를 가지고 있는지 시각적으로 알면 편리합니다. 대신 파이썬 2에서는 항상 __init__.py(비어있는) 배치해야 하며 많은 수를 만들고 결국 init 코드를 어디에 두 었는지 기억하기가 어렵습니다. 이것은 또한 "한 가지 분명한 방법이 있어야한다"는 것과 맞아야한다.
Paolo

148

중대한

@ Mike의 대답은 정확하지만 너무 정확하지 않습니다. Python 3.3 이상 이 파일 없이 패키지를 만들 수있는 암시 적 네임 스페이스 패키지 를 지원한다는 것은 사실입니다 __init__.py.

그러나 이것은 다음에 만 적용됩니다 EMPTY__init__.py 파일 . 따라서 EMPTY__init__.py 파일은 더 이상 필요하지 않으므로 생략 할 수 있습니다. 패키지 또는 해당 모듈 또는 하위 패키지를 가져올 때 특정 초기화 스크립트를 실행하려면 여전히 __init__.py파일이 필요 합니다. 이것은 왜 유용한 지 궁금한 경우 파일을 사용하여 추가 초기화를 수행 하려는 이유에 대한 훌륭한 스택 오버플로 답변 입니다 __init__.py.

디렉토리 구조 예 :

  parent_package/
     __init__.py            <- EMPTY, NOT NECESSARY in Python 3.3+
     child_package/
          __init__.py       <- STILL REQUIRED if you want to run an initialization script
          child1.py
          child2.py
          child3.py

parent_package/child_package/__init__.py:

print("from parent")

실시 예

아래 예제 child_package는 모듈 중 하나를 가져올 때 초기화 스크립트가 실행되는 방법을 보여줍니다 .

예 1 :

from parent_package import child_package  # prints "from parent"

예 2 :

from parent_package.child_package import child1  # prints "from parent"

2
내가 run_script.py같은 디렉토리에 있다고 가정 parent_package하면 from parent_package.child_package import child1없이없이 가져올 수 __init__.py있습니까?
mrgloom

이것의 목적은 some_function이 childX.py에 정의되어 있어도 child_package.some_function을 작성할 수 있습니까? 다시 말해서 사용자가 child_package의 다른 파일에 대해 알 필요가 없습니까? ?
johnbakers

당신이 만드는 왜 그래, 나는하지 않는다 child1.py, child2.py단지에 함께 자신의 코드를 넣는 대신 __init__직접 평.
binki

import 문 __init__이 상대적인 수입품 이 아니어야합니까 from . import child1? 절대 수입품은 ModuleNotFoundError(파이썬 3.6에서)
Halbeard

5
필자의 경험에 따르면 파이썬 3.3 이상에서도 __init__.py하위 폴더를 패키지로 참조하려는 경우와 같이 여전히 빈 공간 이 필요합니다. 예를 들어, 실행 하면 테스트 폴더 아래에 python -m test.foo빈 파일을 만들 때까지 작동하지 않았습니다 __init__.py. 그리고 여기 3.6.6 버전에 대해 이야기하고 있습니다!
Prahlad Yeri

7

당신이 가지고 있다면 setup.py 프로젝트에서 당신이 사용하는 find_packages()그 안에,해야 할 필요가 __init__.py패키지가 자동으로 찾을 수에 대한 모든 디렉토리에 파일을.

패키지는 __init__.py파일 을 포함하는 경우에만 인식됩니다

UPD : 암시 적 네임 스페이스 패키지 __init__.py를 사용 find_namespace_packages()하지 않고 대신 사용하려는 경우

문서


1

암시 적 네임 스페이스 패키지를__init__.py 원할 경우에만 생략해야한다고 말하고 싶습니다 . 그것이 무엇을 의미하는지 모른다면, 아마도 그것을 원하지 않을 것이므로 파이썬 3에서도 짝수를 계속 사용해야합니다 .__init__.py

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.