상세 컨텐츠

본문 제목

변수 범위 variable scope (python)

개발/python-심화(Advanced)

by Matthew0633 2022. 5. 17. 23:32

본문

앞서 병렬처리 부분에서 클로저의 개념을 다루기 전에 변수 범위를 간단하게 다루었는데, 이번에 본격적으로 개념을 정리하고자 한다

전역변수

전역변수는 주로 변하지 않는 상수값 또는 고정값을 가진 변수로 사용하는 것이 일반적이다

a = 10 # Global variable

def foo():
    # Read global variable
    print(a)

foo()    # 10
print(a) # 10

지역변수

지역변수는 함수 내에 로직 해결에 국한되고, 함수 실행 해제 시 소멸되는 특징을 가진다

따라서, 용도와 다르게 global keyword 를 활용하여 전역변수를 지역내에서 수정하는 것은 권장되지 않고 있다

(아래에서 global keyword 에 대해 정리하였다)

b = 20

def bar():
    b = 30    # Local variable
    print(b)  # Read local variable

bar()         # 30 (local variable - b)
print(b)      # 20 (global variable - b)

global keyword 의 사용

전역변수에 대해 함수 내에서 단순히 할당 또는 수정을 시도하면 UnboundLocalError 이 발생하게 된다

c = 40

def foobar():
    # c = c + 10   # UnboundLocalError
    # c = 10
    # c += 100    
    print(c)          

foobar()

에러없이 전역변수를 함수내에서 할당하거나 수정하려면 global 키워드로 전역변수로 명시하면 가능하다

그러나, 이러한 사용은 권장되지 않음 (변수 범위를 벗어난, 직관적이지 않은 사용이므로 혼란을 야기할 수 있기 때문이다)

# Ex4
d = 50
def barfoo():
    global d     
    d = 60       
    print(d) 

barfoo() # 60   
print(d) # 60

nonlocal keyword 의 사용

클로저 형태로 만들어진 함수 내부의 함수가, 지역함수를 수정하거나, 참조하려면 nonlocal 키워드를 사용한다

이 때, 클로저의 자유변수로서, 값의 마지막 상태가 저장된채로 계속 갱신된다

def outer():
    e = 70
    def inner():
        nonlocal e    
        e += 10 # e = e + 10 
        print(e)
    return inner

in_test = outer() # Closure

in_test() # 80          
in_test() # 90

함수 내에서 지역변수를 포함한 namespace를 출력하려면 locals() 를 활용할 수 있다

def func(var): 
    x = 10 
    def printer():
        print("Printer Func Inner") 
    print('Func Inner', locals()) # 함수 내 namespace 출력

func("Hi") # Func Inner {'var': 'Hi', 'x': 10, 'printer': <function func.<locals>.printer at 0x000001D8B6E265E0>}

전역에서도 전역변수를 포함한 namespace를 출력하려면 globals() 를 활용할 수 있다. globals()locals() 는 모두 dict type 으로 속성명과 값을 관리하고 있다. globals() 가 dict type인 것을 활용하여 아래와 같이 전역 변수를 정의할 수도 있다 (test_variable)

print(globals()) # { '__name__': '__main__', .... }

globals()['test_variable'] = 100
print(globals()) # { '__name__': '__main__', .... , 'test_variable': 100 }

globals() 를 활용하여 반복문을 통해 자동으로 값을 원하는 변수명으로 할당하여 전역 변수를 정의할 수 있다

for i in range(1, 10): 
    for k in range(1, 10): 
        globals()[f'plus_{i}_{k}'] = i + k 

print(plus_3_5) # 8
print(plus_9_9) # 18

관련글 더보기

댓글 영역