__all_은 Python에서 무엇을 의미합니까?
, .__all__
__init__.py
들들. 게게??
연결은 언제가 될 것인가 것입니다.__all__
사용됩니다.이것은 모듈의 어떤 기호를 내보낼지 정의하는 문자열 목록입니다.from <module> import *
을 사용하다
를 들어, in, 음음의 입니다.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 *
는 밑줄로 시작하지 않는 모든 기호를 지정된 네임스페이스에서 Import하는 것입니다.
참고 자료: https://docs.python.org/tutorial/modules.html#importing-from-a-package
__all__
을 주다from <module> import *
에 않은 __all__
는 모듈 수 Import를 사용하여 수 있습니다.from <module> import <member>
.
이 리스트는import *
하는 모든 설정보다 밑줄로 시작하는 모든 것을 숨기는 기본 설정보다 우선됩니다.
모두 Python으로 설명하시겠습니까?
가 계속 .
__all__
곳에__init__.py
files.complete files files files files files files files files.이게 뭘 하는 거지?
무인 does does 가 뭐죠?__all__
할수 수 do do do?
모듈로부터 의미론적으로 "퍼블릭" 이름을 선언합니다. __all__
사용자는 그것을 사용할 것으로 예상되며 변경되지 않을 것으로 예상할 수 있습니다.
프로그램 효과도 있습니다.
import *
__all__
모듈에서는 " " " " " "와 같이 입력합니다.module.py
:
__all__ = ['foo', 'Bar']
, ,을 때, 신을 때import *
""에 __all__
Import 상 :
from module import * # imports foo and Bar
문서 도구
및 __all__
모듈에서 사용할 수 있는 이름을 결정합니다.
__init__.py
를 Python .
문서에서:
__init__.py
파일들은 Python이 디렉토리를 패키지를 포함하는 것으로 취급하기 위해 필요합니다.이것은 문자열과 같은 공통 이름을 가진 디렉토리가 모듈 검색 경로에서 나중에 발생하는 유효한 모듈을 의도하지 않게 숨기는 것을 방지하기 위해서입니다.
경우, "는 다음과 같습니다.
__init__.py
는 빈 파일일 하거나 ""를 도 있습니다.__all__
★★★★★★ 。
그...__init__.py
할 수 __all__
패키지용입니다.
API 관리:
수 되어 있는 모듈로 됩니다.__init__.py
Python을 소개합니다.예를 들어 다음과 같은 파일이 패키지에 있다고 가정합니다.
package
├── __init__.py
├── module_1.py
└── module_2.py
다음 파일을 Python 3 쉘에 붙여넣을 수 있도록 Python으로 작성합시다.
from pathlib import Path
package = Path('package')
package.mkdir()
(package / '__init__.py').write_text("""
from .module_1 import *
from .module_2 import *
""")
package_module_1 = package / 'module_1.py'
package_module_1.write_text("""
__all__ = ['foo']
imp_detail1 = imp_detail2 = imp_detail3 = None
def foo(): pass
""")
package_module_2 = package / 'module_2.py'
package_module_2.write_text("""
__all__ = ['Bar']
imp_detail1 = imp_detail2 = imp_detail3 = None
class Bar: pass
""")
이제 다른 사용자가 패키지를 Import할 때 사용할 수 있는 완전한 api를 제시했습니다.
import package
package.foo()
package.Bar()
에는 모듈 시 한 다른 세부 가 모두 되어 있지 package
임스스네
__all__
__init__.py
더 많은 작업을 수행한 후 모듈이 너무 커서(수천 줄 정도) 분할해야 한다고 판단했을 수 있습니다.다음 작업을 수행합니다.
package
├── __init__.py
├── module_1
│ ├── foo_implementation.py
│ └── __init__.py
└── module_2
├── Bar_implementation.py
└── __init__.py
먼저 서브패키지 디렉토리를 모듈과 같은 이름으로 만듭니다.
subpackage_1 = package / 'module_1'
subpackage_1.mkdir()
subpackage_2 = package / 'module_2'
subpackage_2.mkdir()
실장 이동:
package_module_1.rename(subpackage_1 / 'foo_implementation.py')
package_module_2.rename(subpackage_2 / 'Bar_implementation.py')
__init__.py
" " 를 하는 __all__
추가:
(subpackage_1 / '__init__.py').write_text("""
from .foo_implementation import *
__all__ = ['foo']
""")
(subpackage_2 / '__init__.py').write_text("""
from .Bar_implementation import *
__all__ = ['Bar']
""")
패키지 레벨로 프로비저닝된 api가 아직 남아 있습니다.
>>> import package
>>> package.foo()
>>> package.Bar()
<package.module_2.Bar_implementation.Bar object at 0x7f0c2349d210>
또한 서브패키지의 모듈레벨 대신 서브패키지레벨로 관리할 수 있는 것을 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']
「」_
vs 대 __all__
:
Python은 "Python"으로 이름을 ._
Import와 함께 import *
의 셸 알 수 「 」는 「 」입니다import *
은 안 거예요._us_non_public
에서 따온 us.py
★★★★
$ cat us.py
USALLCAPS = "all caps"
us_snake_case = "snake_case"
_us_non_public = "shouldn't import"
$ python
Python 3.10.0 (default, Oct 4 2021, 17:55:55) [GCC 10.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from us import *
>>> dir()
['USALLCAPS', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'us_snake_case']
이 메커니즘은 확실히 신뢰할 수 있습니다.Python 표준 라이브러리의 일부 패키지는 실제로 이 기능에 의존하지만, 이를 위해 에서와 같이 Import에 별칭을 붙입니다.
import os as _os, sys as _sys
「 」의 _
규칙을 사용하면 이름을 다시 명명하는 중복이 제거되므로 보다 우아할 수 있습니다.그러나 Import를 위한 용장성이 추가되어 (많은 경우) 일관되게 이 작업을 수행하는 것을 잊기 쉽습니다.또한 구현 세부사항으로만 의도한 내용을 무기한으로 지원하는 것은 결코 바람직하지 않습니다.단, 이 작업은 단순히 prefix를 붙이는 것을 잊었기 때문입니다._
이치
는 으로 ★★★★★★★★★★★★★★★★★★★★를 쓰고 있습니다.__all__
모듈 개발 라이프 사이클 초기에 내 코드를 사용할 수 있는 다른 사용자가 모듈을 사용해야 하는 것과 사용하지 말아야 하는 것을 알 수 있도록 합니다.
도 ""를 사용합니다.__all__
.
할 때__all__
에 맞다
말을 ._
「」 에 __all__
adda empty:
- 아직 초기 개발 모드에 있고 사용자가 없으며 API를 계속 수정하고 있습니다.
- 사용자가 있을 수 있지만 API를 다루는 unittests를 가지고 있으며, 여전히 API에 적극적으로 추가하고 개발 중에 조정하고 있습니다.
안export
「」를 하는 것의 __all__
내보낼 함수 및 클래스의 이름을 두 번 써야 하며, 이 정보는 정의와 별도로 유지됩니다.우리는 이 문제를 해결하기 위해 장식가를 사용할 수 있다.
나는 데이비드 비즐리의 포장에 관한 강연에서 그런 수출 장식가의 아이디어를 얻었다.이 구현은 CPython의 전통적인 수입업체에서 잘 작동하는 것으로 보입니다. 「Import」에 「Import」의 「Import」의 「Import」의 「Import」의 「Import」의 「Import」의 「Import」의 「Import」에 되돌리기만 하면 됩니다.수동으로 이름을 다시 추가해야 합니다.__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()
메인 실행이든 다른 함수로 Import하든 상관없습니다.
$ cat > run.py
import main
main.main()
$ python run.py
main
API를 사용한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
정확히 말씀드리기 위해 추가하겠습니다.
다른 모든 답변은 모듈에 관한 것입니다.처음에 설명했던 질문은__all__
__init__.py
python 패키지에 대한 내용입니다.
「일부러」__all__
동작하는 것은, 「 」의 뿐입니다.from xxx import *
의 import
스테이트먼트가 사용됩니다.이는 모듈뿐만 아니라 패키지에도 적용됩니다.
모듈의 동작은 다른 답변에 설명되어 있습니다.패키지의 정확한 동작은 여기에 자세히 설명되어 있습니다.
로 말하면, 요,,,__all__
패키지 레벨에서는 (모듈 내의 이름을 지정하는 것과는 대조적으로) 패키지 내의 모듈을 취급하는 것을 제외하고 모듈에서의 동작과 거의 동일합니다.그렇게__all__
、 [ Import ]를 사용할 때 합니다.from package import *
.
가장 큰 차이점은, 선언을 생략했을 때__all__
꾸 a __init__.py
「 「 」라고 하는 문.from package import *
는 아무것도 Import하지 않습니다(단, 매뉴얼에 설명되어 있는 예외는 위의 링크를 참조).
ㅇㅇ를 하면 ㅇㅇㅇㅇ가 됩니다.__all__
모듈에서는 "internal import"에 의해 모듈에 정의된 모든 이름(밑줄로 시작하지 않음)이 Import됩니다.
또한 pydoc에 표시되는 내용도 변경됩니다.
module1.화이
a = "A"
b = "B"
c = "C"
모듈 2화이
__all__ = ['a', 'b']
a = "A"
b = "B"
c = "C"
$pydoc module 1
모듈 1 도움말: 이름모듈 1 파일module1.화이 데이터a = 'A'b = 'B'c = 'C'
$pydoc module 2
모듈 2 도움말: 이름모듈 2 파일모듈 2화이 데이터__all__ = ['a', 'b']a = 'A'b = 'B'
__all__
모든 모듈 및 내부 세부사항에 밑줄을 그으면 라이브 인터프리터 세션에서 사용하지 않은 것을 사용할 때 매우 도움이 됩니다.
__all__
를 커스터마이즈 합니다.*
및 에 있습니다.
모듈은.py
수입하다.
패키지는, 다음의 디렉토리입니다.__init__.py
을. 을. 을. 을. 을. 을. 을. 을. 을. 을. 을. 을. 을. 을. 을. 을. 을. 을. 을. 을. 을.을.
모듈
""" cheese.py - an example module """
__all__ = ['swiss', 'cheddar']
swiss = 4.99
cheddar = 3.99
gouda = 10.99
__all__
는 모듈의 "[@AaronHall]퍼블릭" 기능을 사용자에게 알려줍니다.또한 pydoc이 그들을 [@Longpoke]알아봅니다.
모듈 Import에서*
것은 이쪽swiss
★★★★★★★★★★★★★★★★★」cheddar
네임스페이스로 만, 「」는 아닙니다.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__
하지 않는 기호도 할 수
★★Import를 사용하지 *
을 받지 않다__all__
Import 모듈
>>> import cheese
>>> cheese.swiss, cheese.cheddar, cheese.gouda
(4.99, 3.99, 10.99)
모듈 Import 이름에서
>>> from cheese import swiss, cheddar, gouda
>>> swiss, cheddar, gouda
(4.99, 3.99, 10.99)
로컬명으로 모듈 Import
>>> import cheese as ch
>>> ch.swiss, ch.cheddar, ch.gouda
(4.99, 3.99, 10.99)
패키지
서서 __init__.py
소포를 정리하다 __all__
는 퍼블릭 모듈 또는 기타 객체의 이름을 가진 문자열 목록입니다.수입하다로, 「」는, 「」__all__
*
패키지에서 [@MartinStettner]와일드카드가 검출되었을 경우.
다음은 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...
]
패키지 내의 모든 모듈을 검색하기 위해 파일시스템을 사용하는 경우라는 명백한 동작에 비용이 많이 들기 때문에 기본 대소문자인 아스타리스크는 복잡합니다.대신, 제가 읽은 문서에서는__init__.py
Import 상 :
if
__all__
않습니다.이 정의되어 있지 않습니다.from sound.effects import *
패키지에서 일부 하위 모듈을 Import하지 않음sound.effects
네임스페이스로 만, 할 수 있는 것은, 「패키지」입니다.패키지가sound.effects
Import되었습니다(Import의 를 실행하고 있을 가능성이 ).__init__.py
그런 다음 패키지에 정의된 이름을 가져옵니다.에는 "Submodules및 )에 의해 된 이름이 됩니다.__init__.py
또한 이전 Import 스테이트먼트에 의해 명시적으로 로드된 패키지의 서브모듈도 포함됩니다.
그리고 마지막으로, 스택 오버플로 답변, 교수 및 맨스플라이너에 대한 존경받는 전통은 애초에 질문을 한 것에 대한 비난의 본질이 됩니다.
와일드카드 가져오기...리더와 많은 자동화 툴이 [비밀]되어 있으므로 피해야 합니다.
[PEP 8, @Toolmaker Steve]
단답
__all__
을 주다from <module> import *
★★★★★★★★★★★★★★★★★★.
장답
다음 예를 생각해 보겠습니다.
foo
├── bar.py
└── __init__.py
»foo/__init__.py
:
__all__
, , , 「 」from foo import *
는 Import에 .foo/__init__.py
.을 하는
__all__ = []
, , , 「 」from foo import *
수입하다을 하는
__all__ = [ <name1>, ... ]
, , , 「 」from foo import *
수입하다
은 python으로 _
Import를 사용하면 이러한 수 __all__
.
여기서 Python 문서를 볼 수 있습니다.
__all__
Python API입니다.만, 「 。__all__
사용해야 합니다.
하여 됩니다.
__all__
; 정의되어 있는 경우 해당 모듈에 의해 정의되거나 Import된 일련의 문자열이어야 합니다. 이름__all__
모두 공개로 간주되어 존재해야 합니다. if__all__
정의되어 있지 않습니다.공용 이름 집합에는 밑줄 문자('_')로 시작하지 않는 모듈의 네임스페이스에서 발견된 모든 이름이 포함됩니다.__all__
API를 사용합니다.API의 일부가 아닌 항목(모듈 내에서 Import되어 사용된 라이브러리 모듈 등)을 실수로 내보내는 것을 방지하기 위한 것입니다.
PEP 8은 유사한 표현을 사용하지만 Import된 이름이 퍼블릭 API의 일부가 아님을 명확히 합니다.__all__
존재하지 않습니다.
보다 은 Introspection의 Public API를 .
__all__
설정하다__all__
에 퍼블릭 to empty list가 .[...]
Import된 이름은 항상 구현 세부사항으로 간주해야 합니다.다른 중 한를 들어, 「」 「API」 「 Import 」 등입니다.
os.path
의 「」를 참조해 주세요.__init__
서브모듈에서 기능을 제공하는 모듈입니다.
되듯이 '하다'라는 표현도 있습니다__all__
는 패키지의 와일드카드 Import를 활성화하기 위해 사용됩니다.
되어 다음의 표기법을 합니다.패키지가
__init__.py
는 code라는 이름의 합니다.__all__
、 [ Import ]에 Import 할 때from package import *
을 사용하다
__all__
을 주다from foo import *
본문 내에 코드)는 아스타리스크(「」)를할 수 .*
)에서는from
★★★★★★★★
from foo import *
*
Atribute의 됩니다.foo
(밑줄로 시작하는 변수 제외)는 Import 모듈에서 글로벌 변수로 바인드됩니다.foo
.__all__
은 Atribute, Atribute, Atribute, Atribute의 이 유형에 의해 from
★★★★★★ 。
iffoo
패키지 및 그__init__.py
, 「을합니다.__all__
는, 다음의 경우에 Import 할 필요가 있는 서브 모듈명의 리스트로 간주됩니다.from foo import *
을 사용하다 if__all__
않습니다.이 정의되어 있지 않습니다.from foo import *
수입하다에는 "Submodules및 )에 의해 된 이름이 됩니다.__init__.py
.
:__all__
목록이 될 필요는 없습니다.스테이트먼트에 기재되어 있는 문서에 따라 정의되어 있는 경우,__all__
는 모듈에 의해 정의되거나 Import된 일련의 문자열이어야 합니다.따라서 태플을 사용하여 메모리와 CPU 사이클을 절약할 수 있습니다.모듈이 단일 공용 이름을 정의하는 경우 쉼표를 잊지 마십시오.
__all__ = ('some_name',)
참고 항목: "import *"가 나쁜 이유는 무엇입니까?
이것은, 다음의 PEP8 에 정의되어 있습니다.
글로벌 변수 이름
(이러한 변수는 1개의 모듈 내에서만 사용할 수 있도록 합니다).표기법은 기능에 관한 표기법과 거의 동일합니다.
를 통해
from M import *
해야 요.__all__
글로벌 내보내기를 방지하거나 이러한 글로벌 앞에 언더스코어를 붙이는 오래된 규칙을 사용하는 메커니즘입니다(이러한 글로벌이 "비공개"임을 나타내기 위해 수행할 수 있습니다).
PEP8은 기본 Python 배포판의 표준 라이브러리를 구성하는 Python 코드에 대한 코딩 규칙을 제공합니다.이것을 따라갈수록, 당신은 원래의 의도에 더 가까워진다.
언급URL : https://stackoverflow.com/questions/44834/what-does-all-mean-in-python
'sourcecode' 카테고리의 다른 글
Java 패키지에서 속성 파일 로드 (0) | 2022.12.06 |
---|---|
변환을 방지하기 위해 vuex 상태에서 컬렉션을 복사하는 것이 표준입니까? (0) | 2022.12.06 |
문자열의 MYSQL ORDER BY 번호 (0) | 2022.12.06 |
임의의 IP 주소에서 MySQL 데이터베이스 원격 액세스 허용 (0) | 2022.12.06 |
다른 문자열의 x 위치에 문자열 삽입 (0) | 2022.12.06 |