함수에서 전역 변수 사용


3113

함수에서 전역 변수를 작성하거나 사용하려면 어떻게해야합니까?

한 함수에서 전역 변수를 만들면 다른 함수에서 해당 전역 변수를 어떻게 사용할 수 있습니까? 전역 변수를 액세스가 필요한 함수의 로컬 변수에 저장해야합니까?

답변:


4244

global할당 된 각 함수에서 와 같이 선언하여 다른 함수에서 글로벌 변수를 사용할 수 있습니다 .

globvar = 0

def set_globvar_to_one():
    global globvar    # Needed to modify global copy of globvar
    globvar = 1

def print_globvar():
    print(globvar)     # No need for global declaration to read value of globvar

set_globvar_to_one()
print_globvar()       # Prints 1

그 이유는 전역 변수가 너무 위험하기 때문에 파이썬은 global키워드 를 명시 적으로 요구하여 현재 가지고있는 것이 무엇인지 실제로 알고 싶어하기 때문입니다 .

모듈간에 전역 변수를 공유하려면 다른 답변을 참조하십시오.


838
글로벌을 "너무 위험하다"고 말하는 것은 과장된 일입니다. 세계는 존재하고 존재하는 모든 언어에서 완벽하게 훌륭합니다. 그들은 자신의 자리가 있습니다. 프로그래밍 방법에 대한 단서가 없으면 문제가 발생할 수 있습니다.
Anthony

207
나는 그들이 상당히 위험하다고 생각합니다. 그러나 파이썬에서 "글로벌"변수는 실제로 모듈 수준이므로 많은 문제를 해결합니다.
Fábio Santos

246
파이썬이 global키워드를 요구하는 이유 는 전역이 위험하기 때문에 동의하지 않습니다 . 그보다는 언어가 명시 적으로 변수를 선언 할 필요가없고 달리 지정하지 않는 한 할당 한 변수에 함수 범위가 있다고 자동으로 가정하기 때문입니다. global키워드는 그렇지에게 제공되는 수단이다.
네이트 CK

7
@avgvstvs : 전역이없는 동일한 프로그램을 구현하는 경우 여전히 동일한 수의 코드 경로가 있습니다. 당신이 한 주장은 세계에 반대하는 것이 아닙니다.
궤도에서 가벼움 레이스

13
@LightnessRacesinOrbit 나는 당신의 요점을 얻지 못했습니다. 전역 변수를 제거하면 복잡한 요소를 제거 할 수 있습니다. 이제는 임의의 함수가 더 이상 실행 상태 에서 프로그램 상태를 변경할 수 없으므로 해당 변수에 의존하는 다른 함수에서는 인식 할 수없는 방식으로 실행을 변경할 수 있습니다. 더 이상 " f2()변경 상태 가 변경되었으므로 이제 f3()예상치 못한 일이 발생 했습니까 ?"기능을 추적 할 필요가 없습니다. 기능은 이제 외부 프로그램 상태와
무관하게

775

상황을 올바르게 이해하고 있다면 파이썬이 로컬 (함수) 및 전역 (모듈) 네임 스페이스를 처리하는 방법의 결과입니다.

다음과 같은 모듈이 있다고 가정 해보십시오.

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

당신은이 (42)를 인쇄하는 기대 수도 있지만, 당신은 '추가 할 경우 대신은 5 바와 같이 이미 언급 된 출력 global에'선언을 func1()한 후, func2()42을 인쇄 할 수 있습니다.

def func1():
    global myGlobal
    myGlobal = 42

여기서 일어나고있는 것은 파이썬은 명시 적으로 달리 언급하지 않는 한 함수 내 어디서나에 할당 된 이름이 해당 함수의 로컬 이름이라고 가정합니다 . 이름 만 읽고 있고 이름이 로컬에 존재하지 않으면 포함 범위 (예 : 모듈의 전역 범위)에서 이름을 찾으려고 시도합니다.

myGlobal따라서 name에 42를 할당하면 Python은 같은 이름의 전역 변수를 가리는 로컬 변수를 만듭니다. 그 지역은 범위를 벗어 났고 돌아올 때 가비지 수집 됩니다 func1(). 한편, func2()(수정되지 않은) 글로벌 이름 이외의 다른 것을 볼 수 없습니다. 이 네임 스페이스 결정은 런타임이 아닌 컴파일 타임에 발생합니다. myGlobal내부 값 func1()을 할당하기 전에 내부 값을 읽으면 UnboundLocalErrorPython이 이미 로컬 변수 여야한다고 결정했기 때문에을 얻 습니다. 아직 관련 값이 없습니다. 그러나 ' global'문 을 사용하면 파이썬에게 로컬에 할당하는 대신 다른 곳에서 이름을 찾아야한다고 지시합니다.

(이 동작은 로컬 네임 스페이스의 최적화를 통해 주로 발생했다고 생각합니다.이 동작이 없으면 Python의 VM은 함수 내부에 새 이름이 할당 될 때마다 적어도 세 번의 이름 조회를 수행해야합니다 (이름이 ' t는 이미 모듈 / 내장 레벨에 존재하므로 매우 일반적인 작동 속도가 크게 느려집니다.)


네임 스페이스 결정은 컴파일 타임에 발생한다고 언급했지만 사실이라고 생각하지 않습니다. 나는 파이썬의 편집 배운 내용에서 구문 오류 만 검사를하지 이름 오류 이 예를 시도 데프 A () : X + = 1 , 당신이 그것을 실행하지 않는 경우, 그것은 것입니다 UnboundLocalError을 제공하지 , 확인하시기 바랍니다 감사합니다
watashiSHUN

1
다음과 같은 전역 변수에 대문자를 사용하는 것이 일반적입니다.MyGlobal = 5
Vassilis

3
@watashiSHUN : 네임 스페이스 결정 컴파일 타임에 발생합니다. x로컬로 결정하는 것은 로컬 이름이 처음 사용되기 전에 로컬 이름이 값에 바인드되었는지 런타임시 확인하는 것과 다릅니다.
BlackJack

9
@Vassilis : 대문자로 모든 문자 가 일반적입니다 : MY_GLOBAL = 5. Python 코드 용 스타일 가이드를 참조하십시오 .
BlackJack

223

네임 스페이스 개념을 탐색 할 수 있습니다 . 파이썬에서이 모듈글로벌 데이터를 위한 자연스러운 장소입니다 :

각 모듈에는 자체 개인 심볼 테이블이 있으며,이 모듈은 모듈에 정의 된 모든 기능에서 전역 심볼 테이블로 사용됩니다. 따라서 모듈 작성자는 실수로 사용자의 전역 변수와 충돌 할 염려없이 모듈에서 전역 변수를 사용할 수 있습니다. 반면에, 당신이 무엇을하고 있는지 아는 경우, 기능을 나타내는 데 사용 된 것과 같은 표기법으로 모듈의 전역 변수를 만질 수 있습니다 modname.itemname.

전역 모듈의 특정 사용법은 여기에 설명되어 있습니다- 모듈간에 전역 변수를 공유하는 방법은 무엇입니까? , 그리고 완전성을 위해 내용은 여기에 공유됩니다 :

단일 프로그램 내에서 모듈간에 정보를 공유하는 일반적인 방법은 특수 구성 모듈 (종종 config 또는 cfg ) 을 작성하는 것 입니다. 응용 프로그램의 모든 모듈에서 구성 모듈을 가져 오기만하면됩니다. 그러면 모듈이 전역 이름으로 사용 가능해집니다. 각 모듈에는 하나의 인스턴스 만 있기 때문에 모듈 객체에 대한 변경 사항은 모든 곳에 반영됩니다. 예를 들면 다음과 같습니다.

파일 : config.py

x = 0   # Default value of the 'x' configuration setting

파일 : mod.py

import config
config.x = 1

파일 : main.py

import config
import mod
print config.x

1
내가 config.x 그것을 제거 할 수있는 것을 좋아하지 않는 이유로 ? 에 와서 x = lambda: config.x새로운 가치가 x()있습니다. 어떤 이유로 든 a = config.x나를 위해 속임수 를 쓰지 않습니다.
vladosaurus

3
@vladosaurus가 from config import x해결합니까?
jhylands

93

파이썬은 간단한 휴리스틱을 사용하여 로컬과 전역 사이에서 변수를로드 해야하는 범위를 결정합니다. 변수 이름이 할당의 왼쪽에 나타나지만 전역으로 선언되지 않은 경우 로컬로 간주됩니다. 과제의 왼쪽에 표시되지 않으면 전체적인 것으로 간주됩니다.

>>> import dis
>>> def foo():
...     global bar
...     baz = 5
...     print bar
...     print baz
...     print quux
... 
>>> dis.disassemble(foo.func_code)
  3           0 LOAD_CONST               1 (5)
              3 STORE_FAST               0 (baz)

  4           6 LOAD_GLOBAL              0 (bar)
              9 PRINT_ITEM          
             10 PRINT_NEWLINE       

  5          11 LOAD_FAST                0 (baz)
             14 PRINT_ITEM          
             15 PRINT_NEWLINE       

  6          16 LOAD_GLOBAL              1 (quux)
             19 PRINT_ITEM          
             20 PRINT_NEWLINE       
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE        
>>> 

에서 과제의 왼쪽에 나타나는 baz foo()가 유일한 LOAD_FAST변수 인 방법을 확인하십시오.


12
휴리스틱은 바인딩 작업을 찾습니다 . 할당은 그러한 작업 중 하나이며 다른 작업을 가져옵니다. 그러나 for루프 의 대상 과 asin withexcept문 뒤의 이름 도 바인딩됩니다.
Martijn Pieters

@MartijnPieters 절 as에서 이름을 따온 except것은 나에게 분명하지 않았습니다. 그러나 메모리를 절약하기 위해 자동 삭제됩니다.
로버트

1
@Robert : 메모리를 절약하는 것이 아니라 순환 참조를 생성하지 않아 메모리 누수가 발생할 수 있습니다. 예외는 역 추적을 참조하고 역 추적 as ...은 예외 처리기 의 대상을 포함하여 전체 호출 스택을 따라 모든 로컬 및 전역 네임 스페이스를 참조하기 때문 입니다.
Martijn Pieters

62

함수에서 전역 변수를 참조하려면 global 키워드를 사용하여 전역 변수를 선언 할 수 있습니다 . 모든 경우에이 이름을 사용할 필요는 없습니다 (여기서 누군가가 잘못 주장함). 표현식에서 참조 된 이름을이 함수가 정의 된 함수의 로컬 범위 나 범위에서 찾을 수없는 경우 전역에서 조회됩니다. 변수.

그러나 함수에서 전역으로 선언되지 않은 새 변수에 할당하면 해당 변수가 암시 적으로 로컬로 선언되며 같은 이름의 기존 전역 변수를 숨길 수 있습니다.

또한 전역 변수는 특히 OOP가 과도하게 사용되는 작은 스크립트의 경우 달리 주장하는 일부 OOP 열광 자와 달리 유용합니다.


절대적으로 다시. 열성. 대부분의 Python 사용자는이를 스크립팅에 사용하고 작은 코드를 분리하는 작은 함수를 만듭니다.
Paul Uszak

51

한 함수에서 전역 변수를 만들면 다른 함수에서 해당 변수를 어떻게 사용할 수 있습니까?

다음 함수를 사용하여 전역을 만들 수 있습니다.

def create_global_variable():
    global global_variable # must declare it to be a global first
    # modifications are thus reflected on the module's global scope
    global_variable = 'Foo' 

함수 작성은 실제로 코드를 실행하지 않습니다. 따라서 create_global_variable함수를 호출합니다 .

>>> create_global_variable()

수정하지 않고 전역 사용

객체가 가리키는 객체를 변경하지 않으려는 경우에만 사용할 수 있습니다.

예를 들어

def use_global_variable():
    return global_variable + '!!!'

이제 전역 변수를 사용할 수 있습니다 :

>>> use_global_variable()
'Foo!!!'

함수 내부에서 전역 변수 수정

전역 변수를 다른 객체를 가리 키려면 global 키워드를 다시 사용해야합니다.

def change_global_variable():
    global global_variable
    global_variable = 'Bar'

이 함수를 작성한 후에도 실제로 변경하는 코드는 여전히 실행되지 않습니다.

>>> use_global_variable()
'Foo!!!'

따라서 함수를 호출 한 후 :

>>> change_global_variable()

전역 변수가 변경되었음을 알 수 있습니다. global_variable이름은 이제 포인트 'Bar':

>>> use_global_variable()
'Bar!!!'

파이썬에서 "글로벌"은 진정한 글로벌이 아니며 모듈 수준에 대해서만 글로벌입니다. 따라서 전역적인 모듈로 작성된 기능에만 사용할 수 있습니다. 함수는 작성된 모듈을 기억하므로 다른 모듈로 내보낼 때 여전히 전역 변수를 찾기 위해 작성된 모듈을 찾습니다.

이름이 같은 지역 변수

이름이 같은 지역 변수를 만들면 전역 변수가 숨겨집니다.

def use_local_with_same_name_as_global():
    # bad name for a local variable, though.
    global_variable = 'Baz' 
    return global_variable + '!!!'

>>> use_local_with_same_name_as_global()
'Baz!!!'

그러나 이름이 잘못 지정된 로컬 변수를 사용해도 전역 변수는 변경되지 않습니다.

>>> use_global_variable()
'Bar!!!'

정확히 무엇을하고 있는지 알지 못하는 경우를 제외하고는 전역 변수와 이름이 같은 지역 변수를 사용하지 마십시오. 나는 아직 그런 이유가 발생하지 않았습니다.

우리는 수업에서 같은 행동을 얻습니다

의견에 따라 다음과 같이 묻습니다.

클래스 내의 함수 안에 전역 변수를 만들고 다른 클래스 내의 다른 함수 안에 해당 변수를 사용하려면 어떻게해야합니까?

다음은 정규 함수에서와 동일한 방법으로 메소드에서 동작하는 것을 보여줍니다.

class Foo:
    def foo(self):
        global global_variable
        global_variable = 'Foo'

class Bar:
    def bar(self):
        return global_variable + '!!!'

Foo().foo()

그리고 지금:

>>> Bar().bar()
'Foo!!!'

그러나 전역 변수를 사용하는 대신 클래스 네임 스페이스를 사용하여 모듈 네임 스페이스를 어지럽히 지 않도록 제안합니다. 또한 self여기서는 인수를 사용하지 않습니다. 클래스 메소드 (일반 cls인수 에서 클래스 속성을 변경하는 경우에 유용 ) 또는 정적 메소드 (no self또는 cls) 일 수 있습니다.


멋지지만 클래스 내부의 함수 내에 전역 변수를 만들고 다른 클래스 내의 다른 함수 내부에서 해당 변수를 사용하려면 어떻게해야합니까? Kinda 여기에 붙어
anonmanx

2
@anonmanx 왜 당신이 붙어 있는지 몰라요, 그것은 일반적인 함수에서와 같은 방법으로 동작합니다. 하지만 귀하의 의견과 데모 코드로 답변을 업데이트하겠습니다.
Aaron Hall

1
@anonmanx 어때요?
Aaron Hall

알았어 따라서 전역 변수를 사용하려면 해당 함수를 명시 적으로 호출해야합니다.
anonmanx

47

이미 존재하는 답변 외에도 혼란 스럽습니다.

파이썬에서 함수 내에서만 참조되는 변수는 암시 적으로 전역 입니다. 함수 본문 내에서 변수에 새 값이 할당되면 local로 간주됩니다 . 함수 내에 변수에 새로운 값이 할당 된 경우 변수는 암시 적으로 로컬이므로 명시 적으로 'global'으로 선언해야합니다.

처음에는 조금 놀랐지 만 잠시 생각해 보자. 한편으로, 할당 된 변수에 전역을 요구하면 의도하지 않은 부작용에 대한 막대가 제공됩니다. 반면에 모든 전역 참조에 전역이 필요한 경우 항상 전역을 사용하게됩니다. 내장 함수 또는 가져온 모듈의 구성 요소에 대한 모든 참조를 전역으로 선언해야합니다. 이 혼란은 부작용을 식별하기위한 글로벌 선언의 유용성을 무너 뜨릴 것입니다.

출처 : 파이썬에서 지역 및 전역 변수에 대한 규칙은 무엇입니까? .


34

병렬 실행을 사용하면 발생하는 상황을 이해하지 못하면 전역 변수가 예기치 않은 결과를 초래할 수 있습니다. 다음은 다중 처리 내에서 전역 변수를 사용하는 예입니다. 각 프로세스가 고유 한 변수 사본으로 작동한다는 것을 분명히 알 수 있습니다.

import multiprocessing
import os
import random
import sys
import time

def worker(new_value):
    old_value = get_value()
    set_value(random.randint(1, 99))
    print('pid=[{pid}] '
          'old_value=[{old_value:2}] '
          'new_value=[{new_value:2}] '
          'get_value=[{get_value:2}]'.format(
          pid=str(os.getpid()),
          old_value=old_value,
          new_value=new_value,
          get_value=get_value()))

def get_value():
    global global_variable
    return global_variable

def set_value(new_value):
    global global_variable
    global_variable = new_value

global_variable = -1

print('before set_value(), get_value() = [%s]' % get_value())
set_value(new_value=-2)
print('after  set_value(), get_value() = [%s]' % get_value())

processPool = multiprocessing.Pool(processes=5)
processPool.map(func=worker, iterable=range(15))

산출:

before set_value(), get_value() = [-1]
after  set_value(), get_value() = [-2]
pid=[53970] old_value=[-2] new_value=[ 0] get_value=[23]
pid=[53971] old_value=[-2] new_value=[ 1] get_value=[42]
pid=[53970] old_value=[23] new_value=[ 4] get_value=[50]
pid=[53970] old_value=[50] new_value=[ 6] get_value=[14]
pid=[53971] old_value=[42] new_value=[ 5] get_value=[31]
pid=[53972] old_value=[-2] new_value=[ 2] get_value=[44]
pid=[53973] old_value=[-2] new_value=[ 3] get_value=[94]
pid=[53970] old_value=[14] new_value=[ 7] get_value=[21]
pid=[53971] old_value=[31] new_value=[ 8] get_value=[34]
pid=[53972] old_value=[44] new_value=[ 9] get_value=[59]
pid=[53973] old_value=[94] new_value=[10] get_value=[87]
pid=[53970] old_value=[21] new_value=[11] get_value=[21]
pid=[53971] old_value=[34] new_value=[12] get_value=[82]
pid=[53972] old_value=[59] new_value=[13] get_value=[ 4]
pid=[53973] old_value=[87] new_value=[14] get_value=[70]

25

당신이 말하는 것은 다음과 같은 방법을 사용하는 것입니다.

globvar = 5

def f():
    var = globvar
    print(var)

f()  # Prints 5

그러나 더 좋은 방법은 다음과 같이 전역 변수를 사용하는 것입니다.

globavar = 5
def f():
    global globvar
    print(globvar)
f()   #prints 5

둘 다 동일한 출력을 제공합니다.


25

결과는 항상 간단합니다.

다음은 간단한 예제 모듈로 main정의 에 표시하는 간단한 방법입니다 .

def five(enterAnumber,sumation):
    global helper
    helper  = enterAnumber + sumation

def isTheNumber():
    return helper

main정의 에 표시하는 방법은 다음과 같습니다 .

import TestPy

def main():
    atest  = TestPy
    atest.five(5,8)
    print(atest.isTheNumber())

if __name__ == '__main__':
    main()

이 간단한 코드는 그대로 작동하며 실행됩니다. 도움이 되길 바랍니다.


1
고마워, 나는 파이썬을 처음 접했지만 약간의 자바를 알고있다. 당신이 말한 것이 나를 위해 일했습니다. 글로벌은 <Enter>를 쓰는 클래스 내 .. 내가 전역 A = 4 말할 수 없다 알 .. 함수 쓰기 '세계는'내 것보다 나에게 더 의미가 보인다
barlop

2
이것은 아마도 가장 간단하지만 매우 유용한 파이썬 트릭입니다. 이 모듈의 이름을 지정 하고 시작 스크립트에서 호출되는 global_vars데이터를에서 초기화합니다 init_global_vars. 그런 다음 정의 된 각 전역 변수에 대한 접근 자 메서드를 만듭니다. 나는 이것을 여러 번 공표 할 수 있기를 바랍니다! 고마워 피터!
swdev

1
많은 전역 변수가 있고 전역 명령문 후에 하나씩 하나씩 나열하지 않으려면 어떻게해야합니까?
jtlz2 2016

23

사용하려는 모든 함수에서 전역 변수를 참조해야합니다.

다음과 같이 :

var = "test"

def printGlobalText():
    global var #wWe are telling to explicitly use the global version
    var = "global from printGlobalText fun."
    print "var from printGlobalText: " + var

def printLocalText():
    #We are NOT telling to explicitly use the global version, so we are creating a local variable
    var = "local version from printLocalText fun"
    print "var from printLocalText: " + var

printGlobalText()
printLocalText()
"""
Output Result:
var from printGlobalText: global from printGlobalText fun.
var from printLocalText: local version from printLocalText
[Finished in 0.1s]
"""

3
'사용하려는 모든 기능에서'는 미묘하게 부정확합니다. ' 업데이트 하려는 모든 기능에서 '
spazm

21

실제로 전역 변수를 로컬 변수에 저장하지 않고 원래 전역 참조가 참조하는 것과 동일한 객체에 대한 로컬 참조를 만듭니다. 파이썬의 거의 모든 것이 객체를 가리키는 이름이며 일반적인 작업에서 아무것도 복사되지 않습니다.

식별자가 사전 정의 된 전역을 참조 할시기를 명시 적으로 지정할 필요가없는 경우, 식별자가 대신 새 로컬 변수 인 경우를 명시 적으로 지정해야합니다 (예 : 'var'명령과 같은 것). JavaScript에서 볼 수 있습니다). 로컬 변수는 심각하고 사소한 시스템에서 전역 변수보다 일반적이므로 Python 시스템은 대부분의 경우 더 적합합니다.

당신은 할 수 가 존재하거나하지 않았다 경우 지역 변수를 만드는 경우 전역 변수를 사용하여, 추측 시도 언어를 가지고있다. 그러나 오류가 발생하기 쉽습니다. 예를 들어, 다른 모듈을 가져 오면 실수로 해당 이름으로 글로벌 변수가 도입되어 프로그램의 동작이 변경 될 수 있습니다.


17

이 시도:

def x1():
    global x
    x = 6

def x2():
    global x
    x = x+1
    print x

x = 5
x1()
x2()  # output --> 7


14

계속해서 추가 기능으로 파일을 사용하여 로컬로 선언 된 모든 전역 변수를 포함 한 다음 import as:

파일 initval.py :

Stocksin = 300
Prices = []

파일 getstocks.py :

import initval as iv

def getmystocks(): 
    iv.Stocksin = getstockcount()


def getmycharts():
    for ic in range(iv.Stocksin):

1
전역 변수를 다른 파일로 이동하면 어떤 이점이 있습니까? 전역 변수를 작은 파일로 그룹화하는 것입니까? 그리고 왜 진술을 사용 import ... as ...합니까? 왜 안돼 import ...?
olibre

1
아 ... 나는 이점을 마침내 이해했다 : 키워드를 사용할 필요가 없습니다 global:-) => +1 :-) 다른 사람들이 가질 수있는 심문을 명확히하기 위해 답을 편집하십시오. 건배
올리버

13

전역 배열의 명시 적 요소에 쓰려면 전역 선언이 필요하지 않지만 "도매"에 쓰려면 다음과 같은 요구 사항이 있습니다.

import numpy as np

hostValue = 3.14159
hostArray = np.array([2., 3.])
hostMatrix = np.array([[1.0, 0.0],[ 0.0, 1.0]])

def func1():
    global hostValue    # mandatory, else local.
    hostValue = 2.0

def func2():
    global hostValue    # mandatory, else UnboundLocalError.
    hostValue += 1.0

def func3():
    global hostArray    # mandatory, else local.
    hostArray = np.array([14., 15.])

def func4():            # no need for globals
    hostArray[0] = 123.4

def func5():            # no need for globals
    hostArray[1] += 1.0

def func6():            # no need for globals
    hostMatrix[1][1] = 12.

def func7():            # no need for globals
    hostMatrix[0][0] += 0.33

func1()
print "After func1(), hostValue = ", hostValue
func2()
print "After func2(), hostValue = ", hostValue
func3()
print "After func3(), hostArray = ", hostArray
func4()
print "After func4(), hostArray = ", hostArray
func5()
print "After func5(), hostArray = ", hostArray
func6()
print "After func6(), hostMatrix = \n", hostMatrix
func7()
print "After func7(), hostMatrix = \n", hostMatrix

7

나는 다른 답변에서 보지 못했기 때문에 이것을 추가하고 있으며 비슷한 것으로 고군분투하는 사람에게 유용 할 수 있습니다. 이 globals()함수는 변경 가능한 전역 심볼 딕셔너리를 반환하는데, 여기서 코드의 나머지 부분에서 "마 법적으로"데이터를 사용할 수 있습니다. 예를 들면 다음과 같습니다.

from pickle import load
def loaditem(name):
    with open(r"C:\pickle\file\location"+"\{}.dat".format(name), "rb") as openfile:
        globals()[name] = load(openfile)
    return True

from pickle import dump
def dumpfile(name):
    with open(name+".dat", "wb") as outfile:
        dump(globals()[name], outfile)
    return True

전역 네임 스페이스에서 변수를 덤프 /로드 할 수 있습니다. 매우 편리하고, 무스, 소란이 없습니다. 파이썬 3 전용입니다.


3
globals()항상 로컬 컨텍스트에서 사용 가능한 전역을 반환하므로 여기에서 돌연변이는 다른 모듈에 반영되지 않을 수 있습니다.
Kiran Jonnalagadda 19

6

변경 사항을 표시 할 클래스 네임 스페이스를 참조하십시오.

이 예제에서 러너는 파일 구성에서 max 를 사용 합니다. 러너가 사용할 때 테스트에서 max 값을 변경하고 싶습니다 .

main / config.py

max = 15000

main / runner.py

from main import config
def check_threads():
    return max < thread_count 

tests / runner_test.py

from main import runner                # <----- 1. add file
from main.runner import check_threads
class RunnerTest(unittest):
   def test_threads(self):
       runner.max = 0                  # <----- 2. set global 
       check_threads()

1

멀티 프로세싱 제외

한 쪽에서는 Windows / Mac OS, 다른 쪽에서는 Linux와 같이 다른 플랫폼 / 환경에서의 멀티 프로세싱과 관련된 글로벌은 번거 롭습니다.

나는 당신에게 얼마 전에 겪었던 문제를 지적하는 간단한 예제로 이것을 보여줄 것입니다.

Windows / MacO와 Linux에서 왜 다른지 이해하고 싶다면 새로운 프로세스를 시작하는 기본 메커니즘은 ...

  • Windows / MacO는 'spawn'입니다
  • 리눅스는 '포크'

메모리 할당에서 초기화가 다릅니다 ... (그러나 여기에는 들어 가지 않습니다).

문제 / 예제를 보자 ...

import multiprocessing

counter = 0

def do(task_id):
    global counter
    counter +=1
    print(f'task {task_id}: counter = {counter}')

if __name__ == '__main__':

    pool = multiprocessing.Pool(processes=4)
    task_ids = list(range(4))
    pool.map(do, task_ids)

윈도우

Windows에서 이것을 실행하면 (MacOS에서도 가정) 다음과 같은 결과가 나타납니다 ...

task 0: counter = 1
task 1: counter = 2
task 2: counter = 3
task 3: counter = 4

리눅스

Linux에서 이것을 실행하면 대신 다음을 얻습니다.

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