올바른 / 올바른 패키지 __init__.py 파일을 작성하는 방법


188

내 패키지의 구조는 다음과 같습니다.

mobilescouter/
    __init__.py #1
    mapper/
        __init__.py  #2
        lxml/
            __init__.py #3
            vehiclemapper.py
            vehiclefeaturemapper.py
            vehiclefeaturesetmapper.py
        ...
        basemapper.py
   vehicle/
        __init__.py #4
        vehicle.py
        vehiclefeature.py
        vehiclefeaturemapper.py
   ...

__init__.py파일을 올바르게 작성 하는 방법을 잘 모르겠습니다 . 외모가 좋아 :
__init__.py #1

__all__ = ['mapper', 'vehicle']
import mapper
import vehicle

그러나 예를 들어 어떻게 보 __init__.py #2일까요? 광산은 :

__all__ = ['basemapper', 'lxml']
from basemaper import *
import lxml

언제 사용해야 __all__합니까?


3
코드에서 import *를 사용하는 것은 일반적으로 매우 나쁜 습관이므로 가능하면 피해야합니다. 이것에 대한 좋은 사용 사례는 거의 없지만 실제로는 드 rare니다.
Mayou36

PSA : 좋은 네임 스페이스 패키지 (새로운 종류의 패키지)를 작성하는 방법을 배우고 싶다면 다음 패키지 예를 확인하십시오 : github.com/pypa/sample-namespace-packages
Kyle

답변:


146

__all__매우 좋습니다-모듈을 자동으로 가져 오지 않고 가져 오기 명령문을 안내하는 데 도움이됩니다. http://docs.python.org/tutorial/modules.html#importing-from-a-package

사용 __all__import *중복, __all__필요한 것만

내가 사용하는 가장 강력한 이유 중 하나라고 생각 import *에서 __init__.py수입 패키지에 대한 기존의 응용 프로그램을 깨지 않고 여러 스크립트로 성장했습니다 스크립트를 리팩토링 할 수있을 것입니다. 그러나 처음부터 패키지를 디자인하는 경우. __init__.py파일을 비워 두는 것이 가장 좋습니다 .

예를 들면 다음과 같습니다.

foo.py - contains classes related to foo such as fooFactory, tallFoo, shortFoo

그런 다음 앱이 커지고 이제는 전체 폴더입니다.

foo/
    __init__.py
    foofactories.py
    tallFoos.py
    shortfoos.py
    mediumfoos.py
    santaslittlehelperfoo.py
    superawsomefoo.py
    anotherfoo.py

초기화 스크립트는

__all__ = ['foofactories', 'tallFoos', 'shortfoos', 'medumfoos',
           'santaslittlehelperfoo', 'superawsomefoo', 'anotherfoo']
# deprecated to keep older scripts who import this from breaking
from foo.foofactories import fooFactory
from foo.tallfoos import tallFoo
from foo.shortfoos import shortFoo

변경 중에 다음을 수행하도록 작성된 스크립트가 중단되지 않도록합니다.

from foo import fooFactory, tallFoo, shortFoo

3
나는 ' 전체 '와 한 줄씩 가져 오기 에 대해 매우 혼란 스러웠다 . 귀하의 예는 매우 밝습니다.
Junchen

2
나는 혼란 "야 __all__import *중복", __all__모듈의 소비자가 사용되며, from foo import *.... 다른 사람을 사용하는 모듈 자체에 의해 사용되는
닉 T에게

using __all__ and import * is redundant, only __all__ is needed 그것들은 어떻게 중복됩니까? 그들은 다른 일을합니다.
endolith

113

내 자신의 __init__.py파일이 비어있는 경우가 더 많습니다. 특히, 나는이 결코 from blah import *의 일환으로 __init__.py-, 등의 기능을 직접 정의 된 패키지의 한 부분으로, 그때의 내용을 복사 어휘 것이다 클래스의 모든 종류를 얻는 수단 "패키지 가져 오기"경우 blah.py패키지에있어 __init__.py대신 및 제거 blah.py( 소스 파일의 곱셈은 여기서 좋지 않습니다).

import *관용구 (eek) 를지지한다고 주장한다면 , __all__(자신이 가지고있는 이름의 목록을 미니어처로) 사용 하면 손해 관리에 도움이 될 수 있습니다. 일반적으로 네임 스페이스와 명시 적 가져 오기는 좋은 것이며, 개념 중 하나 또는 둘 다를 우회하여 체계적으로 우회하는 방법을 다시 고려할 것을 강력히 권장합니다!-)


9
개인적으로, 나는 물건을 따로 보관하고 *를 수입하는 것을 선호합니다. 그 이유는 접기와 내용에도 불구하고 관련이 있더라도 클래스가 너무 많은 파일을 탐색하는 것을 싫어하기 때문입니다.
Stefano Borini

5
@stefano는 큰 프레임 워크에 대해 생각합니다. 그것이 사용 import *한다면 당신은 모든 프레임 워크를 무조건 수용해야하며 결코 사용하지 않을 기능도 있습니다. 유지 __init__.py빈주고 당신에게 의미 단지 모 아니면도보다 더 많은 기회를. 꼬인 것에 대해 생각하십시오.
mg.

비워두면 mobilescouter를 가져온 후에도 mobilescouter.mapper 또는 mobilescouter.vehicle 또는 mobilescouter.what을 사용할 수 없습니다. mobilescouter.A, mobilescouter.B .....를 너무 많이 가져 오지 않습니까?
sunqiang 2009

6
@ sunqiang 이것은 개인적이지만 그렇게 생각하지 않습니다. from mobilescouter import A, B코드 한 줄이며 666 클래스의 프로젝트와 자체 파일이있는 모든 프로젝트가 없습니다. import *코드에 둘 이상 이 있으면 네임 스페이스를 잠재적 쓰레기로 채우고 어디에서 A왔는지 빨리 잊게 됩니다. 그리고 상단 패키지가 동일한 경우? 모든 하위 패키지 및 하위 하위 패키지를 가져옵니다. 파이썬의 선과 같이 명시 적은 암시 적보다 낫습니다.
mg.

1
@mg, init .py 파일 에 "import A, B"줄이 있으면 다음 구문을 사용하여 A (또는 B)를 호출 할 수 있습니다. "mobilescouter import A, B에서"를 사용하면 A.something입니다. 언젠가이 줄을 기억하지 못한다. A는 mobilescouter의 하위 팩트이며, 이것이 네임 스페이스 오염에 기여한다고 생각한다. . 균일 한 공용 인터페이스 있도록 초기화는 가져 오기 sub_pkgname의 일을 평.
sunqiang

1

귀하는 __init__.py해야 문서화 문자열을 .

모든 기능이 모듈 및 하위 패키지에 구현되어 있지만 패키지 docstring은 시작 위치를 문서화하는 장소입니다. 예를 들어, python emailpackage를 고려하십시오 . 패키지 문서는 목적, 배경 및 패키지 내의 다양한 구성 요소가 함께 작동하는 방법을 설명하는 소개입니다. 스핑크스 또는 다른 패키지를 사용하여 문서 문자열에서 문서를 자동으로 생성하는 경우 문서 docstring은 이러한 소개를 설명하는 데 가장 적합한 곳입니다.

다른 내용은 firecrowAlex Martelli 의 탁월한 답변을 참조하십시오 .


패키지 의 실제 __init__.py사항 email이이 지침을 준수합니까? "패키지 내의 다양한 구성 요소가 함께 작동하는 방식"을 설명하지 않는 한 줄 docstring이 있습니다.
Gertlex

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