누군가 파이썬에서 __all__을 설명 할 수 있습니까?
저는 Python을 점점 더 많이 사용하고 __all__
있으며 다른 __init__.py
파일에 설정된 변수를 계속 볼 수 있습니다. 누군가 이것이 무엇을 설명 할 수 있습니까?
에 의해 해석되는 해당 모듈의 공용 객체 목록입니다 import *
. 밑줄로 시작하는 모든 항목을 숨기는 기본값을 재정의합니다.
여기에 명시 적으로 언급되지는 않았지만에 링크되어있는 것은 정확히 언제 __all__
사용 되는지 입니다. 모듈에서를 사용할 때 내보낼 모듈의 심볼을 정의하는 문자열 목록입니다 from <module> import *
.
예를 들어의 다음 코드는 및 foo.py
기호를 명시 적으로 내 보냅니다 .bar
baz
__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 packages 에 관한 것 입니다.
일반적으로 문장 __all__
의 from xxx import *
변형 import
이 사용될 때만 작동합니다 . 이는 패키지뿐만 아니라 모듈에도 적용됩니다.
모듈의 동작은 다른 답변에 설명되어 있습니다. 패키지의 정확한 동작은 여기 에 자세히 설명되어 있습니다 .
간단히 말해서, __all__
패키지 수준에서 모듈의 경우와 거의 동일한 작업을 수행합니다. 단 , 패키지 내에서 모듈 을 처리한다는 점만 다릅니다 ( 모듈 내에서 이름 을 지정하는 것과는 대조적으로 ). 그래서 __all__
우리가 사용할 때로드되고 현재 네임 스페이스로 가져올 모든 모듈을 지정합니다 from package import *
.
큰 차이점은 패키지의 선언 을 생략 하면 명령문 이 아무것도 가져 오지 않는다는 것입니다 (문서에 설명 된 예외 사항이있는 경우 위 링크 참조).__all__
__init__.py
from package import *
반면에 __all__
모듈에서 생략 하면 "별표 표시된 가져 오기"는 모듈에 정의 된 모든 이름 (밑줄로 시작하지 않음)을 가져옵니다.
파이썬에서 __all__을 설명 하시겠습니까?
__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
파일은 Python이 디렉토리를 패키지를 포함하는 것으로 취급하도록하는 데 필요합니다. 이는 문자열과 같은 공통 이름을 가진 디렉토리가 나중에 모듈 검색 경로에서 발생하는 유효한 모듈을 의도하지 않게 숨기는 것을 방지하기 위해 수행됩니다.가장 간단한 경우
__init__.py
에는 빈 파일 일 수도 있지만 패키지에 대한 초기화 코드를 실행하거나__all__
변수를 설정할 수도 있습니다.
그래서이 __init__.py
을 선언 할 수 있습니다 __all__
A의 패키지 .
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
그리고 각각 에서 예를 들어 module_1에서 __init__.py
선언합니다 __all__
.
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__
경우 대신 접두사 규칙 을 고수하는 것이 좋습니다 .
- 아직 초기 개발 모드이고 사용자가 없으며 지속적으로 API를 조정하고 있습니다.
- 사용자가있을 수 있지만 API를 다루는 단위 테스트가 있고 여전히 API에 적극적으로 추가하고 개발 중입니다.
export
장식
사용의 단점은 __all__
내보내는 함수와 클래스의 이름을 두 번 작성해야하고 정보가 정의와 별도로 유지된다는 것입니다. 우리는 수 이 문제를 해결하기 위해 장식을 사용합니다.
나는 포장에 관한 David Beazley의 이야기에서 그러한 수출 데코레이터에 대한 아이디어를 얻었습니다. 이 구현은 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
module1 모듈에 대한 도움말 : 이름 module1 파일 module1.py DATA = 'A' , B = 'B' C = 'C'
$ pydoc 모듈 2
module2 모듈에 대한 도움말 : 이름 모듈 2 파일 module2.py DATA __all__ = 'A', 'B'] = 'A' , B = 'B'
저는 __all__
모든 모듈에서 내부 세부 사항을 강조 할뿐만 아니라 라이브 통역 세션에서 이전에 사용하지 않은 것을 사용할 때 정말 도움이됩니다.
에서 (비공식) 파이썬 레퍼런스 위키 :
The public names defined by a module are determined by checking the module's namespace for a variable named
__all__
; if defined, it must be a sequence of strings which are names defined or imported by that module. The names given in__all__
are all considered public and are required to exist. If__all__
is not defined, the set of public names includes all names found in the module's namespace which do not begin with an underscore character ("_").__all__
should contain the entire public API. It is intended to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module).
__all__
customizes the asterisk in from <module> import *
__all__
customizes the asterisk in from <package> import *
A module is a .py
file meant to be imported.
A package is a directory with a __init__.py
file. A package usually contains modules.
MODULES
""" cheese.py - an example module """
__all__ = ['swiss', 'cheddar']
swiss = 4.99
cheddar = 3.99
gouda = 10.99
__all__
lets humans know the "public" features of a module.[@AaronHall] Also, pydoc recognizes them.[@Longpoke]
from module import *
See how swiss
and cheddar
are brought into the local namespace, but not 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
Without __all__
, any symbol (that doesn't start with an underscore) would have been available.
Imports without *
are not affected by __all__
import module
>>> import cheese
>>> cheese.swiss, cheese.cheddar, cheese.gouda
(4.99, 3.99, 10.99)
from module import names
>>> from cheese import swiss, cheddar, gouda
>>> swiss, cheddar, gouda
(4.99, 3.99, 10.99)
import module as localname
>>> import cheese as ch
>>> ch.swiss, ch.cheddar, ch.gouda
(4.99, 3.99, 10.99)
PACKAGES
In the __init__.py
file of a package __all__
is a list of strings with the names of public modules or other objects. Those features are available to wildcard imports. As with modules, __all__
customizes the *
when wildcard-importing from the package.[@MartinStettner]
Here's an excerpt from the Python MySQL Connector __init__.py
:
__all__ = [
'MySQLConnection', 'Connect', 'custom_error_exception',
# Some useful constants
'FieldType', 'FieldFlag', 'ClientFlag', 'CharacterSet', 'RefreshOption',
'HAVE_CEXT',
# Error handling
'Error', 'Warning',
...etc...
]
The default case, asterisk with no __all__
for a package, is complicated, because the obvious behavior would be expensive: to use the file system to search for all modules in the package. Instead, in my reading of the docs, only the objects defined in __init__.py
are imported:
If
__all__
is not defined, the statementfrom sound.effects import *
does not import all submodules from the packagesound.effects
into the current namespace; it only ensures that the packagesound.effects
has been imported (possibly running any initialization code in__init__.py
) and then imports whatever names are defined in the package. This includes any names defined (and submodules explicitly loaded) by__init__.py
. It also includes any submodules of the package that were explicitly loaded by previous import statements.
Wildcard imports ... should be avoided as they [confuse] readers and many automated tools.
[PEP 8, @ToolmakerSteve]
Short answer
__all__
affects from <module> import *
statements.
Long answer
Consider this example:
foo
├── bar.py
└── __init__.py
In foo/__init__.py
:
(Implicit) If we don't define
__all__
, thenfrom foo import *
will only import names defined infoo/__init__.py
.(Explicit) If we define
__all__ = []
, thenfrom foo import *
will import nothing.(Explicit) If we define
__all__ = [ <name1>, ... ]
, thenfrom foo import *
will only import those names.
Note that in the implicit case, python won't import names starting with _
. However, you can force importing such names using __all__
.
You can view the Python document here.
__all__
is used to document the public API of a Python module. Although it is optional, __all__
should be used.
Here is the relevant excerpt from the Python language reference:
The public names defined by a module are determined by checking the module’s namespace for a variable named
__all__
; if defined, it must be a sequence of strings which are names defined or imported by that module. The names given in__all__
are all considered public and are required to exist. If__all__
is not defined, the set of public names includes all names found in the module’s namespace which do not begin with an underscore character ('_').__all__
should contain the entire public API. It is intended to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module).
PEP 8 uses similar wording, although it also makes it clear that imported names are not part of the public API when __all__
is absent:
To better support introspection, modules should explicitly declare the names in their public API using the
__all__
attribute. Setting__all__
to an empty list indicates that the module has no public API.[...]
Imported names should always be considered an implementation detail. Other modules must not rely on indirect access to such imported names unless they are an explicitly documented part of the containing module's API, such as
os.path
or a package's__init__
module that exposes functionality from submodules.
Furthermore, as pointed out in other answers, __all__
is used to enable wildcard importing for packages:
The import statement uses the following convention: if a package’s
__init__.py
code defines a list named__all__
, it is taken to be the list of module names that should be imported whenfrom package import *
is encountered.
__all__
affects how from ... import *
works.
Code that is inside a module body (not in the body of a function or class) may use an asterisk (*
) in a from
statement:
from foo import *
The *
requests that all attributes of module foo
be bound as global variables in the importing module. When foo
has an attribute __all__
, the attribute's value is the list of the names that are bound by this type of from
statement. Otherwise, this type of from
statement binds all attributes of foo
except those beginning with underscores.
Note that __all__
doesn't have to be a list. As per the documentation on the import
statement, if defined, __all__
must be a sequence of strings which are names defined or imported by the module. So you may as well use a tuple to save some memory and CPU cycles. Just don't forget a comma in case the module defines a single public name:
__all__ = ('some_name',)
See also Why is “import *” bad?
This is defined in PEP8 here:
Global Variable Names
(Let's hope that these variables are meant for use inside one module only.) The conventions are about the same as those for functions.
Modules that are designed for use via
from M import *
should use the__all__
mechanism to prevent exporting globals, or use the older convention of prefixing such globals with an underscore (which you might want to do to indicate these globals are "module non-public").
PEP8 provides coding conventions for the Python code comprising the standard library in the main Python distribution. The more you follow this, closer you are to the original intent.
참고URL : https://stackoverflow.com/questions/44834/can-someone-explain-all-in-python
'Program Tip' 카테고리의 다른 글
foreach 루프의 현재 반복 인덱스를 어떻게 얻습니까? (0) | 2020.09.28 |
---|---|
TCP를 통해 ADB로 Android에 연결하려면 어떻게해야합니까? (0) | 2020.09.28 |
`git merge`와`git merge --no-ff`의 차이점은 무엇입니까? (0) | 2020.09.28 |
여러 git 커밋을 되 돌리는 방법은 무엇입니까? (0) | 2020.09.28 |
파이썬에서“assert”의 사용은 무엇입니까? (0) | 2020.09.28 |