문제

내가 사용하는 파이썬 더 많은,나보고 계속 변수 __all__ 설정에서 다른 __init__.py 파일이 있습니다.할 수 있는 누군가를 설명이 무엇입니까?

도움이 되었습니까?

해결책

그것은 목록의 공의 개체는 모듈에 의해 해석 import *.재정의 기본을 숨기는 모든 것에는 시작과 함께 밑줄.

다른 팁

에 연결지만 명시적으로 언급하지 않기 때 정확하게 __all__ 사용됩니다.그것은 목록의 문자열을 정의하는 기호에서 모듈이 수출될 때 from <module> import * 에 사용되는 모듈이 있습니다.

예를 들어,다음 코드는 foo.py 명시적으로 수출은 기호 barbaz:

__all__ = ['bar', 'baz']

waz = 5
bar = 10
def baz(): return 'baz'

이러한 기호로 가져올 수 있습니다.

from foo import *

print(bar)
print(baz)

# The following will trigger an exception, as "waz" is not exported by the module
print(waz)

는 경우 __all__ 위은 주석으로,이 코드를 실행하여 완성으로,기본 행동 import * 을 가져오는 모든 기호하지 않는 밑줄로 시작,에서 지정 네임스페이스가 있습니다.

참고: https://docs.python.org/tutorial/modules.html#importing-from-a-package

참고: __all__ 에 영향을 미치 from <module> import * 행동만 있습니다.회원하지 않는에서 언급된 __all__ 액세스할 수 있습니다 외부에서 모듈을 가져올 수 있습니다진 from <module> import <member>.

나는 단지 이것을 추가 정확:

다른 모든 답변을 참조하여 모듈.원래 질문을 명시 적급 __all____init__.py 파일이므로 이에 대해 python 패키지.

일반적으로, __all__ 만 때 from xxx import * 의 변형 import 문이 사용됩니다.이 패키지뿐만 아니라 모듈을 사용합니다.

행동에 대한 모듈을 설명에 다른 답변이 있습니다.정확한 행동 패키지에 대해 설명 에서 세부 사항입니다.

에서 짧은 __all__ 패키지 레벨은 약과 같은 일을 위해 모듈을 제외하고,그것이 거래 모듈에서의 패키지 (에 대비하여 지정 이름 안에 모듈).그래서 __all__ 을 모두 지정한 모듈을 것로드와 수입으로 현재의 네임스페이스할 때 사용 from package import *.

큰 차이점은,그 때 당신 생략 의 선언 __all__ 에서의 패키지 __init__.py, 문 from package import * 을 가져오지 않습도(예외를 사용 설명서에 설명되어,위의 링크 참조).

다른 한편으로는 경우에,당신은 생략 __all__ 에서 모듈,"주연 가져올 것이다"가져오는 모든 이름(으로 시작하지 않 밑줄)에서 정의한 모듈이다.

설명__모든__에서는 파이썬?

I keep seeing 변수 __all__ 설정에서 다른 __init__.py 파일이 있습니다.

이것은 무엇을 합니까?

무엇 __all__ 니까?

그것은 선언합 의미가"공개"이름에서 모듈이 있다.이 있는 경우에 이름 __all__, 사용자가 사용하는 것으로 예상되고,그들이 가질 수 있는 기대는 그것을 변경되지 않습니다.

그것은 또한 프로그래밍 방식으로 영향을 미칩니다:

import *

__all__ 모듈에서,예를 들어, module.py:

__all__ = ['foo', 'Bar']

는 경우 import * 모듈에서만 그 이름 __all__ 수입:

from module import *               # imports foo and Bar

문서 도구

문서와 코드를 자동 완성 공구 수 있습니다(사실,해야한다)도 검사 __all__ 을 결정하는 것 이름으로 보여주에서 사용할 수 있는 모듈이 있습니다.

__init__.py 만든 디렉토리 Python 패키지

문서:

__init__.py 파일을 만들기 위해 필요하다는 파이썬 치료하는 디렉토리에를 포함하는 것으로 패키지이를 방지하기 위해 수행되는 디렉터리와 일반적인 이름과 같은 문자열에서 실수로 숨기고 유효한 모듈을 나중에 발생하는 모듈에서 검색 경로입니다.

가장 간단한 경우 __init__.py 이 될 수 있습 빈 파일이지만,그것은 또한 수 초기화 코드를 실행한 패키지로 또는 설정 __all__ 변수가 있습니다.

그래서 __init__.py 을 선언할 수 있습니다 __all__패키지.

관리 API:

패키지는 일반적으로 만들어지는 모듈을 가져올 수 있습니다 하지만,반드시 함께 묶여 있는 __init__.py 파일입니다.는 파일은 무엇이 디렉토리로 실제 Python 패키지입니다.예를 들어,당신은 다음과 같다:

 package/
   |-__init__.py # makes directory a Python package
   |-module_1.py
   |-module_2.py

__init__.py 당신이 쓰:

from module_1 import *
from module_2 import *

고서 module_1 이 있:

__all__ = ['foo',]

고서 module_2 이 있:

__all__ = ['Bar',]

이제 당신을 제시한 완전한 api 는 다른 사람할 때 사용할 수 있습니다 그들은 가져오는 당신의 패키지,이렇게:

import package
package.foo()
package.Bar()

그리고 그들은 모든 다른 이름을 만들 때 사용되는 모듈 뒤 섞 package 네임스페이스가 있습니다.

__all____init__.py

더 많은 작업 후,어쩌면 당신이 결정하는 모듈은 너무 크고 필요할 수 있습니다.그래서 다음을 수행할 수 있습니다.

 package/
   |-__init__.py
   |-module_1/
   |  |-__init__.py
   |  |-foo_implementation.py
   |-module_2/
      |-__init__.py
      |-Bar_implementation.py

그리고 각각 __init__.py 당신이 선언 __all__, 예에 module_1:

from foo_implementation import *
__all__ = ['foo']

고 module_2 의 __init__.py:

from Bar_implementation import *
__all__ = ['Bar']

당신은 쉽게 추가할 수 있습니다 일들이 당신의 API 를 관리할 수 있습니다에 분포장 수준 대신에 분포장의 모듈을 수준입니다.를 추가하고 싶다면 새로운 이름을 API,당신은 단순히 업데이트 __init__.py, 예에 module_2:

from Bar_implementation import *
from Baz_implementation import *
__all__ = ['Bar', 'Baz']

그리고 만약 당신이 준비하는 게시 Baz 에서 최고 수준 API 에서,최고 수준 __init__.py 할 수 있다:

from module_1 import *       # also constrained by __all__'s
from module_2 import *       # in the __init__.py's
__all__ = ['foo', 'Bar']     # further constraining the names advertised

과하는 경우 사용자는 인식의 가용성 Baz,그들은 그것을 사용할 수 있다:

import package
package.Baz()

하지만 그렇지 않을 경우 그것에 대해 알고,다른 도구(아 pydoc)을 알리지 않을 것이다.

당신이 나중에 변경이 있는 경우 Baz 라:

from module_1 import *
from module_2 import *
__all__ = ['foo', 'Bar', 'Baz']

___all__:

기본적으로,Python 내보내는 모든 이름으로 시작하지 않는 _.당신은 확실히 에 의존하는 이 메커니즘이 있습니다.일부 패키지에서는 파이썬 표준 라이브러리는 사실, 이것에 의존하지만,이렇게 그들은 자신의 별명을 수입,예를 들어, ctypes/__init__.py:

import os as _os, sys as _sys

를 사용하는 _ 컨벤션할 수 있다 더 우아하고 제거하기 때문에 중복의 이름 이름을 다시합니다.하지만 그것에 추가에 대해 중복 수입(이 있는 경우 그들 중 많은)및 그것은 을 잊을 이렇게 지속적으로-그리고 마지막 것은 당신이 원하는 무기한 지원 뭔가 의도한 대만 구현 세부 정보,당신이 잊고 접두사 _ 이름을 지정할 때에는 기능입니다.

나 개인적으로 쓰 __all__ 초기에는 개발 수명 주기 위해 모듈을 다른 사람들이 그렇게 사용할 수 있습니다 내 코드들이 무엇을 사용해야하고 사용할 수 없습니다.

대부분의 패키지에는 표준 라이브러리 또한 사용 __all__.

면을 피 __all__

그것은 의미를 붙 _ 접두사 컨벤션에 대 __all__ 경우:

  • 당신은 여전히 개발 초기 모드와 사용자가 없고 지속적으로 조정합니다.
  • 어쩌면 당신이 사용자가,하지만 당신은 unittests 는 API,당신은 여전히 적극적으로 추가하는 API 를 조정을 개발 중에 있습니다.

export 장식

의 단점은 사용 __all__ 는 당신의 이름을 작성 함수와 클래스로 수출되고 두 번의 정보는 보관에서 별도로 정의입니다.리 용 장식이 문제를 해결합니다.

나는 아이디어를 가지고 이러한 내보내 장식에서 데이비드 비즐리의 이야기에 포장입니다.이 구현에는 것에서 잘 작동하 CPython 의 전통입니다.이 있는 경우는 특별한 가져오는 훅이나 시스템,나는 그것을 보장하지 않지만,당신이 그것을 채택,그것은 상당히 사소한 다-당신의 아이가 안전하게 수동으로 추가의 이름으로 다시 __all__

그래서 예를 들어,유틸리티는 도서관,을 정의하고 장식:

import sys

def export(fn):
    mod = sys.modules[fn.__module__]
    if hasattr(mod, '__all__'):
        mod.__all__.append(fn.__name__)
    else:
        mod.__all__ = [fn.__name__]
    return fn

그리고,당신은 정의 __all__, 다,당신은 당신이:

$ cat > main.py
from lib import export
__all__ = [] # optional - we create a list if __all__ is not there.

@export
def foo(): pass

@export
def bar():
    'bar'

def main():
    print('main')

if __name__ == '__main__':
    main()

이 잘 작동하는지 여부를으로 실행되는 주 또는 수입에 의해 또 다른 기능이다.

$ cat > run.py
import main
main.main()

$ python run.py
main

과 API 를 통한 프로비저닝 import * 작동합니다:

$ cat > run.py
from main import *
foo()
bar()
main() # expected to error here, not exported

$ python run.py
Traceback (most recent call last):
  File "run.py", line 4, in <module>
    main() # expected to error here, not exported
NameError: name 'main' is not defined

그것은 또한 변화 무엇 pydoc 표시됩니다:

module1.py

a = "A"
b = "B"
c = "C"

module2.py

__all__ = ['a', 'b']

a = "A"
b = "B"
c = "C"

$pydoc 모듈 1

Help on module module1:

이름
    module1

파일
    module1.py

데이터
    a = 'A'
    b = 'B'
    c = 'C'

$pydoc module2

Help on module module2:

이름
    module2

파일
    module2.py

데이터
    __모든__ = ['a', 'b']
    a = 'A'
    b = 'B'

나는 선언 __all__ 내 모든 모듈 뿐만 아니라,밑줄의 내부 세부 사항,이러한 정말로 도울 때 사용하는 것을 사용하기 전에 라이브에서 통역을 세션이 있습니다.

(비공식)Python 참조 Wiki:

공 이름을 정의한 모듈을 결정을 확인하여 모듈의 네임스페이스 라는 변수 __all__;정의된 경우,그것은 시퀀스의 문자열 이름을 정의하거나 수입되는 모듈이 있습니다.이름에서 주어 __all__ 모두 고려 대중과하는 데 필요한 존재합니다.는 경우 __all__ 를 정의하지 않는 설정의 공개 이름을 포함한 모든 이름에서 발견된 모듈의 네임스페이스하지 않는 밑줄로 시작하는 문자("_"). __all__ 을 포함해야 하는 전체 공공합니다.기 위한 것입을 피하는 실수로 내보내는 항목하지 않는 API(도서관 같은 모듈을 수입되었고 내에서 사용되는 모듈).

__all__ 사용자 지정 별표from <module> import *

__all__ 사용자 지정 별표from <package> import *


A 모듈.py 파일을 의미를 가져올 수 있습니다.

A 패키지 은 디렉토리 __init__.py 파일입니다.패키지 일반적으로 포함되어 모듈을 사용합니다.


모듈

""" cheese.py - an example module """

__all__ = ['swiss', 'cheddar']

swiss = 4.99
cheddar = 3.99
gouda = 10.99

__all__ 할 수 있는 인간 알고있는"공개"기능 모듈.[@AaronHall] 또한,pydoc 인식합니다.[@Longpoke]

모듈 가져오기*

시는 방법 swisscheddar 는 로컬 네임스페이스,지 gouda:

>>> from cheese import *
>>> swiss, cheddar
(4.99, 3.99)
>>> gouda
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'gouda' is not defined

__all__, 모든 기호(는 시작하지 않는 밑줄)되었을 것이 가능합니다.


수입이 없 * 에 의해 영향을 받지 않습 __all__


가져오기 모듈

>>> import cheese
>>> cheese.swiss, cheese.cheddar, cheese.gouda
(4.99, 3.99, 10.99)

모듈 가져오기 이름

>>> from cheese import swiss, cheddar, gouda
>>> swiss, cheddar, gouda
(4.99, 3.99, 10.99)

가져오기 모듈하 여

>>> import cheese as ch
>>> ch.swiss, ch.cheddar, ch.gouda
(4.99, 3.99, 10.99)

패키지

__init__.py 파일의 패키지 __all__ 목록과 함께 문자열 이름에 공공의 모듈이나 다른 물체.이러한 기능은 사용하는 와일드카드를 가져옵니다.으로 모듈 __all__ 사용자 지정 * 경우 와일드카드를 가져와서는 패키지입니다.[@MartinStettner]

여기에서 발췌 Python MySQL 커넥터 __init__.py:

__all__ = [
    'MySQLConnection', 'Connect', 'custom_error_exception',

    # Some useful constants
    'FieldType', 'FieldFlag', 'ClientFlag', 'CharacterSet', 'RefreshOption',
    'HAVE_CEXT',

    # Error handling
    'Error', 'Warning',

    ...etc...

    ]

기본 경우, 별표 없 __all__ 패키지, 은 복잡하기 때문에,분명한 행동은 비싼 것:하는 파일 시스템을 사용하여 검색에 대한 모든 모듈에서의 패키지입니다.대신에,나의 문서,단체에서 정의 __init__.py 수입:

는 경우 __all__ 를 정의하지 않 statement from sound.effects import * 가져오는 모든 서브 모듈에서의 패키지 sound.effects 현재의 네임스페이스;그것은 단지는 것을 보장 패키지 sound.effects 가져온(가능하게 실행되는 초기화 코드 __init__.py 다)및 그 수입이 어떤 이름에서 정의합니다.이 포함한 모든 이름을 정의한(및 서브 모듈을 명시적으로드)에 의하여 __init__.py.그것은 또한 포함한 모든 서브 모듈의 패키지에는 명시적으로 로드하여 이전 가져오는 문입니다.


와일드카드 수입...피해야 합니다 그들[혼동하]독자들과 많은 자동화된 도구입니다.

[PEP8,@ToolmakerSteve]

짧은 대답

__all__ 영향 from <module> import * 문입니다.

긴 답변

다음 예제를 살펴보십시오:

foo
├── bar.py
└── __init__.py

foo/__init__.py:

  • (암시)지 않는 경우 우리는 정의 __all__, 다음 from foo import * 만 가져오는 이름에서 정의 foo/__init__.py.

  • (Explicit)면 우리는 정의 __all__ = [], 다음 from foo import * 가져올 것이 아무것도 아니다.

  • (Explicit)면 우리는 정의 __all__ = [ <name1>, ... ], 다음 from foo import * 만 가져오는 그 이름이 있습니다.

참고에서 암시적 경우,python 지 않을 것이 가져오기로 시작하는 이름 _.그러나,당신은 당신할 수 있는 힘을 가져오는 같은 이름을 사용하여 __all__.

당신이 볼 수 있는 파이썬 문서 .

__all__ 서 공개 API 의 Python 모듈이 있습니다.하지만 그것은 선택사항 __all__ 을 사용해야 합니다.

여기에 관련 에서 발췌 Python 언어 참조:

공 이름을 정의한 모듈을 결정을 확인하여 모듈의 네임스페이스 라는 변수 __all__;정의된 경우,그것은 시퀀스의 문자열 이름을 정의하거나 수입되는 모듈이 있습니다.이름에서 주어 __all__ 모두 고려 대중과하는 데 필요한 존재합니다.는 경우 __all__ 를 정의하지 않는 설정의 공개 이름을 포함한 모든 이름에서 발견된 모듈의 네임스페이스하지 않는 밑줄로 시작하는 문자('_'). __all__ 을 포함해야 하는 전체 공공합니다.기 위한 것입을 피하는 실수로 내보내는 항목하지 않는 API(도서관 같은 모듈을 수입되었고 내에서 사용되는 모듈).

PEP8 사용하는 유사한 표현이 있지만,그것은 또한 분명히 가져오는 이름의 일부가 아닌 공개 API 때 __all__ 가 없:

를 위한 지원이 반성,모듈을 명시적으로 선언한 이름에 자신의 공중 API 를 사용하여 __all__ 특성이 있습니다.설정 __all__ 빈 목록을 나타내는 모듈은 아니합니다.

[...]

수입한 이름이 항상 고려되어야 구현한 세부 사항입니다.다른 모듈을해야합에 의존하지 않는 간접적으로 접근하는 등 이름을 가져온지 않는 한 그들이 명시적으로 문서화의 일부분을 포함하는 모듈 API 등 os.path 나의 패키지 __init__ 모듈 기능을 제공합에서 하위 모듈.

또한,지적에서 다른 답변, __all__ 을 활성화하는 데 사용됩니다 와일드카드 가져오기 위해 패키지:

수입 문의는 다음 규칙을 사용합니다:는 경우 패키지 __init__.py 코드 목록을 정의합 이름 __all__,그것은 목록에 모듈 이름의 반입해야 하는 경우 from package import * 이 발생했습니다.

또한 기존의 답변, __all__ 어야 하지 않는다.에 따라 문서 import 문의, 정의된 경우, __all__문자열의 시퀀스 는 이름을 정의하거나 의해 수입되는 모듈이 있습니다.그래서를 사용할 수 있는 튜플을 저장 일부 CPU 와 메모리 사이클이 있습니다.그냥 잊지 않는 쉼표는 경우 모듈을 정의하는 하나의 공개 이름:

__all__ = ('some_name',)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top