문제

그만큼 __debug__ 변수는 모든 모듈에 영향을 주기 때문에 부분적으로 편리합니다.같은 방식으로 작동하는 다른 변수를 만들고 싶다면 어떻게 해야 합니까?

변수(원래대로 'foo'라고 부르자)는 실제로 전역적일 필요는 없습니다. 즉, 한 모듈에서 foo를 변경하면 다른 모듈에서도 업데이트된다는 의미입니다.다른 모듈을 가져오기 전에 foo를 설정할 수 있으면 괜찮을 것입니다. 그러면 동일한 값이 표시됩니다.

도움이 되었습니까?

해결책

나는이 솔루션을 어떤 식 으로든 모양이나 형태로 보증하지 않습니다. 그러나 변수를 추가하면 __builtin__ 모듈은 포함 된 다른 모듈의 글로벌처럼 액세스 할 수 있습니다. __builtin__ - 기본적으로 모든 것입니다.

A.py는 포함됩니다

print foo

b.py는 포함합니다

import __builtin__
__builtin__.foo = 1
import a

결과는 "1"이 인쇄되었습니다.

편집하다: 그만큼 __builtin__ 모듈은 로컬 기호로 사용할 수 있습니다 __builtins__ - 이것이이 두 가지 답변 사이의 불일치의 이유입니다. 또한 주목하십시오 __builtin__ 이름이 바뀌 었습니다 builtins python3에서.

다른 팁

글로벌 크로스 모드 변수가 필요한 경우 간단한 글로벌 모듈 수준 변수로 충분할 수 있습니다.

A.Py :

var = 1

b.py :

import a
print a.var
import c
print a.var

C.py :

import a
a.var = 2

테스트:

$ python b.py
# -> 1 2

실제 예 : django의 global_settings.py (django 앱에서는 물체 django.conf.settings).

모듈을 정의하고 ( "GlobalBaz") 변수를 정의하십시오. 이 "pseudoglobal"을 사용하는 모든 모듈은 "GlobalBaz"모듈을 가져 와서 "globalbaz.var_name"을 사용하여 참조해야합니다.

이것은 변경 장소에 관계없이 수입 전후에 변수를 변경할 수 있습니다. 가져온 모듈은 최신 값을 사용합니다. (나는 장난감 예에서 이것을 테스트했다)

설명을 위해 GlobalBaz.py는 다음과 같습니다.

var_name = "my_useful_string"

나는 그것이 의미가있는 많은 상황이 있다고 생각하며, 여러 (단단히 결합 된) 모듈에서 알려진 일부 글로벌을 갖도록 프로그래밍을 단순화합니다. 이 정신으로, 나는 그것들을 참조 해야하는 모듈로 가져온 글로벌 모듈을 가지고 있다는 아이디어에 대해 조금 자세히 설명하고 싶습니다.

그러한 모듈이 하나만 있으면 "g"의 이름을 지정합니다. 그것에서, 나는 글로벌로 취급하려는 모든 변수에 대해 기본값을 할당합니다. 이들 중 하나를 사용하는 각 모듈에서 "g import var"에서 사용하지 않습니다. 이로 인해 가져 오기 시점에서만 G에서 초기화되는 로컬 변수 만 발생합니다. 나는 G.Var 형식과 "g"형식으로 대부분의 참고 문헌을 만든다. 다른 모듈에 잠재적으로 액세스 할 수있는 변수를 다루고 있음을 상기시켜줍니다.

이러한 글로벌 변수의 값이 모듈의 일부 함수에서 자주 사용되는 경우 해당 함수는 로컬 사본을 만들 수 있습니다 : var = g.var. 그러나 VAR에 대한 과제는 로컬이며 G.Var를 과제에서 명시 적으로 참조하지 않고는 Global G.Var를 업데이트 할 수 없습니다.

모듈의 다른 서브 세트에서 공유하는 여러 글로벌 모듈을 가질 수도 있습니다. 글로벌 모듈에 짧은 이름을 사용하는 이유는 코드가 너무 혼란을 겪지 않기 때문입니다. 약간의 경험만으로, 그들은 1 또는 2 자만으로 충분히 니모닉이됩니다.

X가 G로 정의되지 않았을 때 GX에 할당 할 수 있으며 다른 모듈은 GX에 액세스 할 수 있지만 통역사가 허용 하더라도이 접근법은 그렇게 투명하지 않으며 피하십시오. 그것. 할당의 변수 이름으로 오타의 결과로 실수로 G에 실수로 새로운 변수를 생성 할 가능성이 여전히 있습니다. 때로는 DIR (G)에 대한 검사가 그러한 사고로 인해 발생했을 수있는 놀라운 이름을 발견하는 데 유용합니다.

하나의 모듈의 글로벌을 Onother로 전달할 수 있습니다.

모듈 A에서 :

import module_b
my_var=2
module_b.do_something_with_my_globals(globals())
print my_var

모듈 B에서 :

def do_something_with_my_globals(glob): # glob is simply a dict.
    glob["my_var"]=3

글로벌 변수는 일반적으로 나쁜 생각이지만 다음에 할당하여이를 수행 할 수 있습니다. __builtins__:

__builtins__.foo = 'something'
print foo

또한 모듈 자체는 모든 모듈에서 액세스 할 수있는 변수입니다. 따라서 호출 된 모듈을 정의하면 my_globals.py:

# my_globals.py
foo = 'something'

그런 다음 어디서나 사용할 수 있습니다.

import my_globals
print my_globals.foo

수정보다는 모듈을 사용합니다 __builtins__ 일반적으로 이런 종류의 글로벌을하는 더 깨끗한 방법입니다.

모듈 수준 변수로 이미이 작업을 수행 할 수 있습니다. 모듈은 어떤 모듈에서 가져 오든 상관없이 동일합니다. 따라서 변수를 모듈 수준 변수로 만들 수있는 모든 모듈에서 모듈 수준 변수를 넣고 액세스하거나 다른 모듈에서 할당 할 수 있습니다. 변수의 값을 설정하거나 일부 싱글 톤 객체의 특성으로 만들기 위해 함수를 호출하는 것이 좋습니다. 이렇게하면 변수가 변경 될 때 일부 코드를 실행 해야하는 경우 모듈의 외부 인터페이스를 깨지 않고도 할 수 있습니다.

글로벌을 사용하는 것은 일반적으로 일을하는 좋은 방법은 아닙니다. 그러나 이것이 가장 깨끗한 방법이라고 생각합니다.

변수가 찾을 수없는 경우가 있다는 답을 게시하고 싶었습니다.

주기적 수입은 모듈 동작을 중단 할 수 있습니다.

예를 들어:

첫 번째 .py

import second
var = 1

두 번째 .py

import first
print(first.var)  # will throw an error because the order of execution happens before var gets declared.

main.py

import first

이것에 대한 예는 분명해야하지만 큰 코드 기반에서는 실제로 혼란 스러울 수 있습니다.

이것은 수정하는 것 같습니다 __builtin__ 이름 공간. 그것을 위해 :

import __builtin__
__builtin__.foo = 'some-value'

사용하지 마십시오 __builtins__ 직접 (추가 "S"를 알아 차리기 - 분명히 이것은 사전 또는 모듈 일 수 있습니다. 이것을 지적 해 주신 τζωτζιου 덕분에 더 많은 것을 찾을 수 있습니다. 여기.

지금 foo 어디에서나 사용할 수 있습니다.

일반적 으로이 작업을 수행하지는 않지만이를 사용하는 것은 프로그래머에게 달려 있습니다.

할당하는 것은 위와 같이 수행해야합니다. foo = 'some-other-value' 현재 네임 스페이스에서만 설정합니다.

나는 실제로 부족하다고 느꼈던 몇 가지 기본 내장 기능에 이것을 사용합니다.한 가지 예는 필터, 맵, 축소와 동일한 사용법 의미를 갖는 찾기 함수입니다.

def builtin_find(f, x, d=None):
    for i in x:
        if f(i):
            return i
    return d

import __builtin__
__builtin__.find = builtin_find

이것이 실행되면(예를 들어 진입점 근처에서 가져옴) 모든 모듈은 분명히 내장된 것처럼 find()를 사용할 수 있습니다.

find(lambda i: i < 0, [1, 3, 0, -5, -10])  # Yields -5, the first negative.

메모: 물론 길이가 0인지 테스트하기 위해 필터와 다른 줄을 사용하거나 이상한 줄의 축소를 사용하여 이 작업을 수행할 수 있지만 항상 이상하다고 느꼈습니다.

교차 모듈 수정 가능 (또는 변하기 쉬운) 사전을 사용하여 변수 :

# in myapp.__init__
Timeouts = {} # cross-modules global mutable variables for testing purpose
Timeouts['WAIT_APP_UP_IN_SECONDS'] = 60

# in myapp.mod1
from myapp import Timeouts

def wait_app_up(project_name, port):
    # wait for app until Timeouts['WAIT_APP_UP_IN_SECONDS']
    # ...

# in myapp.test.test_mod1
from myapp import Timeouts

def test_wait_app_up_fail(self):
    timeout_bak = Timeouts['WAIT_APP_UP_IN_SECONDS']
    Timeouts['WAIT_APP_UP_IN_SECONDS'] = 3
    with self.assertRaises(hlp.TimeoutException) as cm:
        wait_app_up(PROJECT_NAME, PROJECT_PORT)
    self.assertEqual("Timeout while waiting for App to start", str(cm.exception))
    Timeouts['WAIT_JENKINS_UP_TIMEOUT_IN_SECONDS'] = timeout_bak

시작할 때 test_wait_app_up_fail, 실제 시간 초과 지속 시간은 3 초입니다.

전역 변수 사용의 단점 중 일부를 피하는 것이 가능한지 궁금했습니다(예: http://wiki.c2.com/?GlobalVariablesAreBad) 전역/모듈 네임스페이스 대신 클래스 네임스페이스를 사용하여 변수 값을 전달합니다.다음 코드는 두 메서드가 본질적으로 동일함을 나타냅니다.아래 설명과 같이 클래스 네임스페이스를 사용하면 약간의 이점이 있습니다.

다음 코드 조각에서는 전역/모듈 네임스페이스와 클래스 네임스페이스 모두에서 특성이나 변수가 동적으로 생성 및 삭제될 수 있음을 보여줍니다.

wall.py

# Note no definition of global variables

class router:
    """ Empty class """

변수를 튕겨내는 데 사용되기 때문에 이 모듈을 '벽'이라고 부릅니다.빈 클래스 '라우터'의 전역 변수와 클래스 차원의 속성을 임시로 정의하는 공간 역할을 하게 됩니다.

소스.py

import wall
def sourcefn():
    msg = 'Hello world!'
    wall.msg = msg
    wall.router.msg = msg

이 모듈은 벽을 가져오고 단일 기능을 정의합니다. sourcefn 이는 메시지를 정의하고 두 가지 다른 메커니즘, 즉 전역을 통해 하나, 라우터 기능을 통해 하나를 통해 메시지를 내보냅니다.변수는 wall.msg 그리고 wall.router.message 각각의 네임스페이스에서 처음으로 여기에서 정의됩니다.

dest.py

import wall
def destfn():

    if hasattr(wall, 'msg'):
        print 'global: ' + wall.msg
        del wall.msg
    else:
        print 'global: ' + 'no message'

    if hasattr(wall.router, 'msg'):
        print 'router: ' + wall.router.msg
        del wall.router.msg
    else:
        print 'router: ' + 'no message'

이 모듈은 함수를 정의합니다 destfn 이는 두 가지 다른 메커니즘을 사용하여 소스에서 방출된 메시지를 수신합니다.이는 'msg' 변수가 존재하지 않을 가능성을 허용합니다. destfn 또한 변수가 표시된 후에는 변수를 삭제합니다.

main.py

import source, dest

source.sourcefn()

dest.destfn() # variables deleted after this call
dest.destfn()

이 모듈은 이전에 정의된 함수를 순서대로 호출합니다.첫 통화 후 dest.destfn 변수 wall.msg 그리고 wall.router.msg 더이상 존재하지 않는다.

프로그램의 출력은 다음과 같습니다.

글로벌:안녕하세요!
라우터:안녕하세요!
글로벌:메시지 없음
라우터:메시지 없음

위의 코드 조각은 모듈/전역 및 클래스/클래스 변수 메커니즘이 본질적으로 동일하다는 것을 보여줍니다.

많은 변수를 공유해야 하는 경우 여러 벽형 모듈을 사용하여 네임스페이스 오염을 관리할 수 있습니다.벽1, 벽2 등또는 단일 파일에 여러 라우터 유형 클래스를 정의하여 가능합니다.후자는 약간 더 깔끔하므로 클래스 변수 메커니즘을 사용하는 데 있어 약간의 이점을 나타낼 수 있습니다.

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