[python] __init__.py에 코드 추가

장고의 모델 시스템이 어떻게 작동하는지 살펴보고 있는데 이해가 안되는 부분을 발견했습니다.

__init__.py현재 디렉터리가 패키지임을 지정하기 위해 빈 파일을 만드는 것을 알고 있습니다 . 그리고 __init__.pyimport *가 제대로 작동하도록 몇 가지 변수를 설정할 수 있습니다 .

그러나 django는 from … import … 문을 추가하고 __init__.py. 왜? 이것은 단지 일을 지저분하게 보이게하지 않습니까? 이 코드가 필요한 이유가 __init__.py있습니까?



답변

__init__.py포함 된 패키지 (디렉토리)를 가져올 때 모든 가져 오기를 사용할 수 있습니다.

예:

./dir/__init__.py:

import something

./test.py:

import dir
# can now use dir.something

편집 : 언급하는 것을 잊었습니다 __init__.py. 해당 디렉토리에서 모듈을 처음 가져올 때 코드가 실행됩니다. 따라서 일반적으로 패키지 수준 초기화 코드를 넣는 것이 좋습니다.

EDIT2 : dgrant는 내 예에서 가능한 혼란을 지적했습니다. In __init__.py import something은 패키지에서 필요하지 않은 모든 모듈을 가져올 수 있습니다. 예를 들어으로 바꿀 수 있습니다 import datetime. 그러면 최상위 수준 test.py에서 다음 코드 조각이 모두 작동합니다.

import dir
print dir.datetime.datetime.now()

import dir.some_module_in_dir
print dir.datetime.datetime.now()

결론은 다음과 같습니다. __init__.py가져온 모듈, 함수 또는 클래스에 관계없이에 할당 된 모든 이름 은 패키지 또는 패키지의 모듈을 가져올 때마다 패키지 네임 스페이스에서 자동으로 사용할 수 있습니다.


답변

그것은 실제로 개인적인 취향이며 파이썬 모듈의 레이아웃과 관련이 있습니다.

라는 모듈이 있다고 가정 해 보겠습니다 erikutils. 거기는 모듈 될 수 있다는 두 가지 방법이 있습니다, 하나는라는 파일이 erikutils.py을 당신에 sys.path또는 당신이라는 디렉토리가 erikutils 온을 sys.path빈과 __init__.py그 안에 파일. 그럼 당신이 전화 모듈의 무리가 있다고 가정하자 fileutils, procutils, parseutils그리고 당신이 그 미만의 서브 모듈이되고 싶어요 erikutils. 따라서 fileutils.py , procutils.pyparseutils.py 라는 .py 파일을 만듭니다 .

erikutils
  __init__.py
  fileutils.py
  procutils.py
  parseutils.py

어쩌면 당신은하지에 속하지 않는 몇 가지 기능을 가지고 fileutils, procutils또는 parseutils모듈을. 라는 새 모듈을 만들고 싶지 않다고 가정 해 보겠습니다 miscutils. 그리고 다음과 같이 함수를 호출 할 수 있기를 원합니다.

erikutils.foo()
erikutils.bar()

하기보다는

erikutils.miscutils.foo()
erikutils.miscutils.bar()

그래서 erikutils모듈은 파일이 아니라 디렉토리 이기 때문에 우리는 내부에 함수를 정의해야합니다.__init__.py 합니다.

장고에서 내가 생각할 수있는 가장 좋은 예는 django.db.models.fields. 모든 django * Field 클래스는 django / db / models / fields 디렉토리 의 __init__.py파일에 정의되어 있습니다 . 나는 그들이 가상으로 학원의 모든 것을 원하지 않았기 때문에 그들이 이런 짓을 생각 장고 / DB / 모델 / fields.py 모델들은 (몇 서브 모듈로를 분할 있도록 related.py , files.py 예를 들어,)와 그들은 만들어진 * Field 정의를 fields 모듈 자체에 붙였습니다 (따라서 __init__.py).


답변

사용 __init__.py 파일하면 외부에서 내부 패키지 구조 보이지 않게 할 수 있습니다. 내부 구조가 변경되면 (예 : 하나의 지방 모듈을 두 개로 분할하기 때문에)__init__.py 파일 되지만 패키지에 의존하는 코드는 되지 않습니다. 예를 들어 일반적으로 사용할 준비가되지 않은 경우 패키지의 일부를 보이지 않게 만들 수도 있습니다.

del명령을 사용할 수 있으므로 일반적인 __init__.py것은 다음과 같습니다.

from somemodule import some_function1, some_function2, SomeObject

del somemodule

이제 분할하기로 결정한 경우 somemodule새 항목 __init__.py은 다음과 같습니다.

from somemodule1 import some_function1, some_function2
from somemodule2 import SomeObject

del somemodule1
del somemodule2

외부에서 보면 패키지는 여전히 이전과 동일하게 보입니다.


답변