__init__.py를 사용하여 전역 변수를 정의 할 수 있습니까?


130

패키지의 모든 하위 모듈에서 사용할 수있는 상수를 정의하고 싶습니다. 가장 좋은 장소는 __init__.py루트 패키지 파일에 있다고 생각했습니다 . 그러나 나는 이것을하는 법을 모른다. 하위 패키지가 몇 개 있고 각각 여러 개의 모듈이 있다고 가정합니다. 이 모듈에서 해당 변수에 어떻게 액세스 할 수 있습니까?

물론 이것이 완전히 잘못되고 더 좋은 대안이 있다면 알고 싶습니다.

답변:


196

에 넣을 수 있어야합니다 __init__.py. 이것은 항상 이루어집니다.

mypackage/__init__.py:

MY_CONSTANT = 42

mypackage/mymodule.py:

from mypackage import MY_CONSTANT
print "my constant is", MY_CONSTANT

그런 다음 mymodule을 가져옵니다.

>>> from mypackage import mymodule
my constant is 42

여전히 상수가있는 경우 별도의 모듈 (constants.py, config.py, ...)에 배치하고 패키지 네임 스페이스에 원하는 경우 가져 오기가 합리적입니다 (아마도 모범 사례). 그들.

mypackage/__init__.py:

from mypackage.constants import *

여전히 패키지 모듈의 네임 스페이스에 상수가 자동으로 포함되지는 않습니다. 패키지의 각 모듈은 여전히 mypackage또는에서 상수를 명시 적으로 가져와야 mypackage.constants합니다.


19
이것은 받아 들여진 대답이어야합니다. 뿐만 아니라 설명한대로 파이썬 2.5로 작업하는 이상 당신은 또한 명시 적으로 상대 가져 오기를 사용할 수있는 경우 여기에 : from . import MY_CONSTANT
ThatAintWorking

두 번째 방법은 상수에만 작동하지 않습니까? 동일한 변수에 대한 참조가 아닌 모든 서브 모듈에 from mypackage.constants import *사본을 배치 MY_CONSTANT합니다
hardmooth

@hardmooth : 정확하지 않습니다. 값은 참조로 복사되므로 MY_CONSTANT모듈 중 하나를 변경하면 모든 위치에서 변경됩니다. MY_CONSTANT모듈 중 하나 를 다시 할당 하면 해당 모듈에만 영향을줍니다. 그것이 당신의 의도라면, 속성으로 참조해야합니다 mypackage.constants.MY_CONSTANT.
Jason R. Coombs

7
가져올 경우, 예를 한 가지 캐치는 mymodule.py__init__.py이전 MY_CONSTANT = 42수입이 때 때문에 실패 할 것이다 mymodule.py MY_CONSTANT아직 정의되지 않았습니다. 필요가 이동 그래서 MY_CONSTANT = 42import mymodule
markmnl

변수는 어떻습니까? 상수가 아니라 변수에 대해 묻습니다. 파이썬은 패키지 내부의 변수를 어떻게 처리합니까? 패키지 내부의 변수가 변경된 경우 어떻게됩니까?
TomSawyer

31

당신은 그렇게 할 수 없습니다. 상수를 각 개별 모듈의 네임 스페이스로 명시 적으로 가져와야합니다. 이를 달성하는 가장 좋은 방법은 "config"모듈에서 상수를 정의하고 필요한 곳 ​​어디에서나 가져 오는 것입니다.

# mypackage/config.py
MY_CONST = 17

# mypackage/main.py
from mypackage.config import *

예, 구성 파일이 내가 원하는 것입니다. init .py가 좋은 곳 이라고 생각했습니다 . 솔루션은 표준 연습처럼 들립니다. 그렇습니까?
Andrei Vajna II

1
좋은 지적. 나는 모든 패키지 모듈의 네임 스페이스에 상수를 자동으로 배치 하는 것이 문제라는 것을 몰랐다 .
Jason R. Coombs

그러나 스크립트가 config.py를 가져올 때마다 내부 코드가 실행됩니다. config.py 내부의 코드를 한 번만 실행하려면 어떻게해야합니까? config.py에서 settings.json 파일을 읽는 중이고 config.py를 가져올 때마다 파일을 열고 싶지 않다고 가정 해보십시오.
Augiwan

@UGS 이것은 파이썬이 작동하는 방식이 아닙니다. 모든 모듈은 한 번만 실행됩니다. 두 번째로 가져올 때는 모듈이 이미 캐시되어 sys.modules있습니다.
페르디난트 바이어

@FerdinandBeyer 죄송합니다! 동일한 스크립트가 아닌 여러 스크립트에서 config.py를 가져오고 있음을 언급하지 않았습니다. a.py가 config.py & b.py를 가져오고 b.py가 config.py를 가져오고 있다고 가정하십시오. config.py 내부의 코드가 한 번만 실행될 수 있는지 궁금합니다.
Augiwan

2

어디에서나 전역 변수를 정의 할 수 있지만 실제로는 좋지 않습니다. __builtin__모듈을 가져오고이 모듈의 속성을 수정하거나 추가하면 갑자기 새로운 내장 상수 또는 함수가 생깁니다. 사실, 내 응용 프로그램이 gettext를 설치할 때 아무것도 가져 오지 않고 모든 모듈에서 _ () 함수를 얻습니다. 따라서 이것은 가능하지만 재사용 가능한 패키지 나 모듈이 아닌 응용 프로그램 유형 프로젝트에만 해당됩니다.

그리고 아무도이 방법을 추천하지 않을 것입니다. 네임 스페이스에 어떤 문제가 있습니까? 고 말했다 응용 프로그램은 내가 좋아하는 사용 가능한 "글로벌"변수가 그래서, 버전 모듈이 version.VERSION, version.PACKAGE_NAME


0

상수를 config.ini 파일을 사용하여 사용하고 configparser 라이브러리를 사용하여 스크립트에서 구문 분석 할 수 있음을 추가하고 싶었습니다. 이런 식으로 여러 상황에서 상수를 가질 수 있습니다. 예를 들어 두 개의 개별 URL 요청에 대한 매개 변수 상수가있는 경우 다음과 같이 레이블을 지정하십시오.

mymodule/config.ini
[request0]
conn = 'admin@localhost'
pass = 'admin'
...

[request1]
conn = 'barney@localhost'
pass = 'dinosaur'
...

파이썬 웹 사이트의 문서가 매우 유용하다는 것을 알았습니다. 파이썬 2와 3 사이에 차이점이 있는지 확실하지 않으므로 여기에 대한 링크가 있습니다.

Python 3의 경우 : https://docs.python.org/3/library/configparser.html#module-configparser

Python 2의 경우 : https://docs.python.org/2/library/configparser.html#module-configparser

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