문제

무엇인가요 __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

  1. 편의를 위해 : 다른 사용자는 패키지 계층 구조에서 기능의 정확한 위치를 알 필요가 없습니다.

    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
    
  2. 무언가를 초기화하려는 경우; 예를 들어 로깅 (최상위 레벨에 넣어야 함) :

    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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top