Python 소스 디렉토리에서 __init__.py
는 무엇입니까?
__init__.py는 무엇을 위한 것입니까?
질문자 :Mat
이전에는 패키지의 필수 부분이었습니다( 이전, 3.3 이전 "일반 패키지" , 최신 3.3+ "네임스페이스 패키지" 아님).
Python은 일반 패키지와 네임스페이스 패키지의 두 가지 유형의 패키지를 정의합니다. 일반 패키지는 Python 3.2 및 이전 버전에 존재했던 기존 패키지입니다.
__init__.py
파일이 포함된 디렉토리로 구현됩니다. 일반 패키지를 가져오면 이__init__.py
파일이 암시적으로 실행되고 이 파일이 정의하는 개체는 패키지의 네임스페이스에 있는 이름에 바인딩됩니다.__init__.py
파일은 다른 모듈이 포함할 수 있는 것과 동일한 Python 코드를 포함할 수 있으며 Python은 가져올 때 모듈에 몇 가지 추가 속성을 추가합니다.
__init__.py
없는 패키지 종류인 네임스페이스 패키지에 대한 설명이 포함되어 있습니다.
Loki
__init__.py
라는 파일은 디스크의 디렉토리를 Python 패키지 디렉토리로 표시하는 데 사용됩니다. 파일이 있는 경우
mydir/spam/__init__.py mydir/spam/module.py
mydir
이 경로에 있으면 module.py
의 코드를 다음과 같이 가져올 수 있습니다.
import spam.module
또는
from spam import module
__init__.py
파일을 제거하면 Python은 더 이상 해당 디렉토리 내에서 하위 모듈을 찾지 않으므로 모듈 가져오기 시도가 실패합니다.
__init__.py
파일은 일반적으로 비어 있지만 더 편리한 이름으로 패키지의 선택된 부분을 내보내고, 편의 기능을 유지하는 등의 데 사용할 수 있습니다. 위의 예에서 init 모듈의 내용은 다음과 같이 액세스할 수 있습니다.
import spam
에 따라 이
caritos
디렉토리에 Python 패키지로 레이블을 지정하고 __all__
__init__.py
사용하면 패키지 수준에서 모든 변수를 정의할 수 있습니다. 패키지가 API와 같은 방식으로 자주 가져올 항목을 정의하는 경우 그렇게 하는 것이 종종 편리합니다. 이 패턴은 Pythonic "flat is better than nested" 철학을 준수하도록 촉진합니다.
예
다음은 내 데이터베이스와 상호 작용하기 위해 Session
이라는 sessionmaker
자주 가져오는 내 프로젝트 중 하나의 예입니다. 몇 가지 모듈로 "데이터베이스" 패키지를 작성했습니다.
database/ __init__.py schema.py insertions.py queries.py
내 __init__.py
에는 다음 코드가 포함되어 있습니다.
import os from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine engine = create_engine(os.environ['DATABASE_URL']) Session = sessionmaker(bind=engine)
Session
정의하므로 아래 구문을 사용하여 새 세션을 시작할 수 있습니다. 이 코드는 "database" 패키지 디렉토리 내부 또는 외부에서 실행되는 것과 동일합니다.
from database import Session session = Session()
물론 이것은 작은 편리함입니다. 대안은 내 데이터베이스 패키지의 "create_session.py"와 같은 새 파일에 Session
from database.create_session import Session session = Session()
추가 읽기
__init__.py
적절한 사용을 다루는 꽤 흥미로운 reddit 스레드가 있습니다.
http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/
대다수 의견은 "명시적인 것이 암시적인 것보다 낫다"는 철학을 위반하지 않도록 __init__.py
Nathan Gould
__init__.py
에는 2가지 주요 이유가 있습니다.
편의상: 다른 사용자는 패키지 계층에서 함수의 정확한 위치를 알 필요가 없습니다.
your_package/ __init__.py file1.py file2.py ... fileN.py
# in __init__.py from file1 import * from file2 import * ... from fileN import *
# in file1.py def add(): pass
그러면 다른 사람들은 다음과 같이 add()를 호출할 수 있습니다.
from your_package import add
file1을 모르는 상태에서
from your_package.file1 import add
초기화를 원하는 경우 예를 들어, 로깅(최상위 레벨에 있어야 함):
import logging.config logging.config.dictConfig(Your_logging_config)
flycee
__init__.py
파일은 파이썬이 그것을 포함하는 디렉토리를 모듈로 취급하게 합니다.
또한 모듈에 로드되는 첫 번째 파일이므로 모듈이 로드될 때마다 실행하려는 코드를 실행하거나 내보낼 하위 모듈을 지정할 수 있습니다.
Can Berk Güder
Python 3.3부터 __init__.py
는 디렉토리를 가져올 수 있는 Python 패키지로 정의하는 데 더 이상 필요하지 않습니다.
__init__.py
마커 파일이 필요하지 않고 자동으로 여러 경로 세그먼트에 걸쳐 있을 수 있는 패키지 디렉토리에 대한 기본 지원 (PEP 420에 설명된 대로 네임스페이스 패키지에 대한 다양한 타사 접근 방식에서 영감을 얻음)
테스트는 다음과 같습니다.
$ mkdir -p /tmp/test_init $ touch /tmp/test_init/module.py /tmp/test_init/__init__.py $ tree -at /tmp/test_init /tmp/test_init ├── module.py └── __init__.py $ python3 >>> import sys >>> sys.path.insert(0, '/tmp') >>> from test_init import module >>> import test_init.module $ rm -f /tmp/test_init/__init__.py $ tree -at /tmp/test_init /tmp/test_init └── module.py $ python3 >>> import sys >>> sys.path.insert(0, '/tmp') >>> from test_init import module >>> import test_init.module
참조:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
Python 3의 패키지에는 __init__.py가 필요하지 않습니까?
zeekvfu
__init__.py
파일 없이 작동하지만 여전히 포함해야 합니다.
디렉토리가 패키지로 취급되어야 함을 지정하므로 이를 포함합니다(비어 있더라도).
__init__.py
파일을 사용할 수 있는 경우도 있습니다.
다음과 같은 파일 구조가 있다고 상상해보십시오.
main_methods |- methods.py
그리고 methods.py
에는 다음이 포함되어 있습니다.
def foo(): return 'foo'
foo()
를 사용하려면 다음 중 하나가 필요합니다.
from main_methods.methods import foo # Call with foo() from main_methods import methods # Call with methods.foo() import main_methods.methods # Call with main_methods.methods.foo()
아마도 거기에 main_methods
(예: 런타임/종속성) 안에 methods.py
main_methods
있습니다.
methods.py
의 이름을 __init__.py
main_methods
가져와서 foo()
를 사용할 수 있습니다.
import main_methods print(main_methods.foo()) # Prints 'foo'
__init__.py
가 패키지의 일부로 취급되기 때문에 작동합니다.
일부 Python 패키지는 실제로 이 작업을 수행합니다. 예는 JSON을 사용하는 것입니다 . 여기서 import json
실행하면 실제로 json
패키지에서 __init__.py
를 가져옵니다(여기에서 패키지 파일 구조 참조 ).
소스 코드:
Lib/json/__init__.py
Simon
Python에서 패키지의 정의는 매우 간단합니다. Java와 마찬가지로 계층 구조와 디렉토리 구조는 동일합니다. 그러나 패키지에 __init__.py
가 있어야 합니다. 아래 예를 들어 __init__.py
파일을 설명하겠습니다.
package_x/ |-- __init__.py |-- subPackage_a/ |------ __init__.py |------ module_m1.py |-- subPackage_b/ |------ __init__.py |------ module_n1.py |------ module_n2.py |------ module_n3.py
__init__.py
는 존재하는 한 비어 있을 수 있습니다. 디렉토리가 패키지로 간주되어야 함을 나타냅니다. 물론 __init__.py
도 적절한 내용을 설정할 수 있습니다.
module_n1에 함수를 추가하면:
def function_X(): print "function_X in module_n1" return
실행 후:
>>>from package_x.subPackage_b.module_n1 import function_X >>>function_X() function_X in module_n1
그런 다음 계층 패키지를 따라 module_n1 함수를 호출했습니다. 다음과 같이 subPackage_b에서 __init__.py
를 사용할 수 있습니다.
__all__ = ['module_n2', 'module_n3']
실행 후:
>>>from package_x.subPackage_b import * >>>module_n1.function_X() Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named module_n1
따라서 * 가져오기를 사용하면 모듈 패키지에 __init__.py
내용이 적용됩니다.
Marcus Thornton
__init__.py
는 해당 디렉토리를 로드 가능한 모듈로 취급합니다.
코드 읽기를 선호하는 사람들을 위해 여기에 Two-Bit Alchemist의 설명을 넣었습니다.
$ find /tmp/mydir/ /tmp/mydir/ /tmp/mydir//spam /tmp/mydir//spam/__init__.py /tmp/mydir//spam/module.py $ cd ~ $ python >>> import sys >>> sys.path.insert(0, '/tmp/mydir') >>> from spam import module >>> module.myfun(3) 9 >>> exit() $ $ rm /tmp/mydir/spam/__init__.py* $ $ python >>> import sys >>> sys.path.insert(0, '/tmp/mydir') >>> from spam import module Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named spam >>>
B.Mr.W.
다른 파이썬 파일을 쉽게 가져올 수 있습니다. 이 파일을 다른 py 파일을 포함하는 디렉토리(예: 물건)에 배치하면 import stuff.other와 같은 작업을 수행할 수 있습니다.
root\ stuff\ other.py morestuff\ another.py
디렉토리 물건 안에 이 __init__.py
없으면 other.py를 가져올 수 없습니다. 파이썬은 물건의 소스 코드가 어디에 있는지 모르고 그것을 패키지로 인식할 수 없기 때문입니다.
Epitaph
__init__.py
파일을 사용하면 쉽게 가져올 수 있습니다. __init__.py
가 패키지 내에 b.py
과 같이 a()
를 가져올 수 있습니다.
from b import a
그러나 이것이 없으면 직접 가져올 수 없습니다. 시스템 경로를 수정해야 합니다.
import sys sys.path.insert(0, 'path/to/b.py') from b import a
Alec
__init__.py가 허용하는 한 가지는 API를 중단하거나 관련 없는 중첩된 네임스페이스 또는 개인 모듈*을 생성하지 않고 모듈을 패키지로 변환하는 것입니다. 이것은 네임스페이스를 확장하고 싶을 때 도움이 됩니다.
다음을 포함하는 util.py 파일이 있는 경우
def foo(): ...
그러면 사용자는 다음을 사용하여 foo
에 액세스합니다.
from util import foo
그런 다음 데이터베이스 상호 작용을 위한 유틸리티 기능을 추가하고 util
아래에 고유한 네임스페이스를 갖기를 원하면 새 디렉토리**가 필요하고 API 호환성을 유지하기 위해 ( from util import foo
계속 작동하도록), 나는 그것을 util/이라고 부를 것이다. util.py를 util/로 이동할 수 있습니다.
util/ __init__.py util.py db.py
util/__init__.py에서
from util import *
그러나 이것은 중복됩니다. util/util.py 파일 대신 util.py 내용을 __init__.py에 넣으면 사용자는 이제
from util import foo from util.db import check_schema
util
util
모듈과 유사한 방식으로 작동하는 방식을 훌륭하게 강조한다고 생각합니다.
* 이것은 다른 답변에 암시되어 있지만 여기에서 강조하고 싶습니다.
** 수입 체조 채용 부족. 파일과 동일한 이름으로 새 패키지를 생성하는 것은 작동하지 않습니다. 이것을 참조하십시오.
joel
출처 : http:www.stackoverflow.com/questions/448271/what-is-init-py-for