__init__.py는 무엇입니까?
-
19-08-2019 - |
문제
무엇인가요 __init__.py
Python 소스 디렉토리에 있습니까?
해결책
패키지의 필수 부분이었습니다 (오래된 3.3 Pre-3.3 "일반 패키지", 아니다 최신 3.3+ "네임 스페이스 패키지").
Python은 두 가지 유형의 패키지, 일반 패키지 및 네임 스페이스 패키지를 정의합니다. 일반 패키지는 Python 3.2 이상에 존재했던 전통적인 패키지입니다. 일반 패키지는 일반적으로 다음을 포함하는 디렉토리로 구현됩니다.
__init__.py
파일. 일반 패키지가 가져 오면이__init__.py
파일은 암시 적으로 실행되며, 정의하는 객체는 패키지 네임 스페이스의 이름에 바인딩됩니다. 그만큼__init__.py
파일에는 다른 모듈이 포함 할 수있는 동일한 Python 코드가 포함될 수 있으며 Python은 가져 오면 모듈에 추가 속성을 추가합니다.
그러나 링크를 클릭하면 예제, 자세한 정보 및 네임 스페이스 패키지에 대한 설명, 패키지의 종류가 포함되어 있습니다. __init__.py
.
다른 팁
이름이 지정된 파일 __init__.py
디스크의 디렉토리를 파이썬 패키지 디렉토리로 표시하는 데 사용됩니다. 파일이있는 경우
mydir/spam/__init__.py
mydir/spam/module.py
그리고 mydir
경로에 있으면 코드를 가져올 수 있습니다. module.py
~처럼
import spam.module
또는
from spam import module
당신이 제거하면 __init__.py
파일, Python은 더 이상 해당 디렉토리 내부의 하위 모듈을 찾지 않으므로 모듈을 가져 오려는 시도가 실패합니다.
그만큼 __init__.py
파일은 일반적으로 비어 있지만 더 편리한 이름으로 패키지의 선택된 부분을 내보내는 데 사용될 수 있습니다.
import spam
기반 이것
디렉토리를 파이썬 패키지로 라벨링하고 정의하는 것 외에도 __all__
, __init__.py
패키지 레벨에서 변수를 정의 할 수 있습니다. 패키지가 API와 같은 방식으로 자주 가져올 것을 정의하는 경우 종종 편리합니다. 이 패턴은 Pythonic "Flat가 중첩 된 것보다 낫다"철학을 준수합니다.
예
다음은 내 프로젝트 중 하나의 예입니다. sessionmaker
~라고 불리는 Session
내 데이터베이스와 상호 작용하려면 몇 가지 모듈이있는 "데이터베이스"패키지를 작성했습니다.
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
여기서 아래 구문을 사용하여 새 세션을 시작할 수 있습니다. 이 코드는 "데이터베이스"패키지 디렉토리의 내부 또는 외부에서 실행 된 것과 동일합니다.
from database import Session
session = Session()
물론 이것은 작은 편의입니다. 대안은 정의하는 것입니다. Session
내 데이터베이스 패키지의 "create_session.py"와 같은 새 파일에서 다음을 사용하여 새 세션을 시작합니다.
from database.create_session import Session
session = Session()
추가 독서
적절한 용도를 다루는 꽤 흥미로운 Reddit 스레드가 있습니다. __init__.py
여기:
http://www.reddit.com/r/python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/
대다수의 의견은 바로 그 것 같습니다 __init__.py
"명시 적은 암시 적보다 낫다"철학을 위반하지 않도록 파일은 매우 얇아야합니다.
두 가지 주요 이유가 있습니다 __init__.py
편의를 위해 : 다른 사용자는 패키지 계층 구조에서 기능의 정확한 위치를 알 필요가 없습니다.
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
파일 1을 알지 못하고
from your_package.file1 import add
무언가를 초기화하려는 경우; 예를 들어 로깅 (최상위 레벨에 넣어야 함) :
import logging.config logging.config.dictConfig(Your_logging_config)
그만큼 __init__.py
파일은 파이썬 처리 디렉토리를 모듈로 포함합니다.
또한이 파일은 모듈에로드되는 첫 번째 파일이므로 모듈을로드 할 때마다 실행할 코드를 실행하거나 내보내는 하위 모듈을 지정할 수 있습니다.
파이썬 3.3 이후 __init__.py
더 이상 디렉토리를 수입 가능한 Python 패키지로 정의 할 필요가 없습니다.
확인하다 PEP 420 : 암시 적 네임 스페이스 패키지:
필요없는 패키지 디렉토리에 대한 기본 지원
__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-musplicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
Python 3의 패키지에는 __init__.py가 필요하지 않습니까?
파이썬에서 패키지의 정의는 매우 간단합니다. 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을 함수라고합니다. 우리는 사용할 수 있습니다 __init__.py
Subpackage_B에서 : 다음과 같습니다.
__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
콘텐츠.
Python은 __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()
어쩌면 거기에 보관해야 할 수도 있습니다. methods.py
내부에 main_methods
(예: 런타임/종속성) 하지만 가져오기만 원합니다. main_methods
.
이름을 변경한 경우 methods.py
에게 __init__.py
그럼 당신은 사용할 수 있습니다 foo()
그냥 수입해서 main_methods
:
import main_methods
print(main_methods.foo()) # Prints 'foo'
이것은 작동합니다. __init__.py
패키지의 일부로 처리됩니다.
일부 Python 패키지는 실제로 이 작업을 수행합니다.예는 다음과 같습니다. JSON, 실행 중인 곳 import json
실제로 수입하고 있어요 __init__.py
~로부터 json
패키지 (여기에서 패키지 파일 구조를 참조하세요.):
소스 코드:
Lib/json/__init__.py
__init__.py
디렉토리를로드 가능한 모듈로 처리합니다.
읽기 코드를 선호하는 사람들에게는 내가 넣습니다 2 비트 연금술사 여기에 댓글을 달아라.
$ 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
>>>
다른 Python 파일 가져 오기를 용이하게합니다. 이 파일을 다른 PY 파일을 포함하는 디렉토리 (예 : 물건)에 배치하면 import stuff.other와 같은 작업을 수행 할 수 있습니다.
root\
stuff\
other.py
morestuff\
another.py
이것없이 __init__.py
디렉토리 내부에서 Python은 Source Code가 위치하는 위치를 알지 못하고 패키지로 인식 할 수 없기 때문에 Other.py를 가져올 수 없었습니다.
an __init__.py
파일은 가져 오기를 쉽게 만듭니다. 언제 __init__.py
패키지 내에 존재합니다 a()
파일에서 가져올 수 있습니다 b.py
그렇게 :
from b import a
그러나 그것 없이는 직접 가져올 수 없습니다. 시스템 경로를 수정해야합니다.
import sys
sys.path.insert(0, 'path/to/b.py')
from b import a