Variable scope

EBAB!·2024년 1월 15일
0
post-custom-banner

파이썬을 사용하다보면 함수를 정말 많이 만들게 된다. 특히 협업할 때는 수행할 일을 명확하게 전해주기 위해 인풋과 아웃풋을 알려주고 그것을 수행하는 함수를 작성하게 된다.

이렇게 함수를 작성하다보면 변수 영역이 상당히 중요하다. 전역 변수인지, 로컬 변수인지, 데코레이터 형식에서 사용되는 로컬 변수는 어떻게 다룰지 등등..

중요한건 몰라도 잘 구현하지만 좋은 코드가 아니라는 점이다. 어떻게 보면 간단하고 명확하게 알지 않아도 구현하는데 어려움이 없는 개념이기에 지나치기 쉽고 안좋은 코딩 방식이 고착화될 가능성이 높다고 생각되는 부분이다.

때문에 변수의 영역에 대해 깊지 않지만 정확하게 짚기 위한 포스터를 작성해본다.



Variable scope

Global, Local Variable

전역 변수는 특정 함수나 클래스가 아닌 스크립트 영역에 선언된 변수로 어느 영역에서든 접근이 가능하다.

지역 변수는 당연히 해당 영역에서만 사용 가능하다.
다른 언어에서는 전역, 지역 변수의 이름이 겹친다면 지역 후 전역 변수를 사용하지만 파이썬에서는 global이라는 명확한

var = 10

print(var)  # 10

def fn():
	var = 20
    print(var)  # 20
    
def gn():
	print(var)  # Error
    
def foo():
	global var
    var += 100
    print(var)  # 110

global로 가져온 변수는 전역변수를 읽고 수정까지 할 수 있지만 pythonic한 코드도 아니고 권장되는 코드 스타일도 아니다. 전역 변수를 특정 부분에서 수정한다면 다른 곳에서 전역 변수를 사용할 때 영향을 받기 때문이다.
전역 변수는 주로 변하지 않는 고정 값에 사용하는 것이 옳다.

개인적으로 global을 쓴 경험이 있긴했다.
FastAPI에서 딥러닝 모델을 사용하는데 GPU에 단 한 번만 올려놓아야 하는 상황이였다.

  1. model=None을 전역변수로 선언하고
  2. FastAPI가 실행될 때 model=DLModel()로 초기화
  3. 다른 코드에서 해당 모델을 가져와서 사용

Closure

Closure 형식에서는 nonlocal이 사용될 수 있다.
스코프 내의 하위 스코프가 있을 때, 하위 스코프가 상위 스코프의 지역 변수를 사용할 수 있는 방법이다.

Closure

어떤 함수의 내부 함수가 외부 함수의 변수를 참조할 때, 외부 함수가 종료되어도 내부 함수가 외부 함수의 변수를 참조할 수 있도록 어딘가에 저장하는 함수

조건

  • 어떤 함수의 내부 함수일 것
  • 내부 함수가 외부 함수의 변수를 참조할 것
  • 외부 함수가 내부 함수를 리턴할 것
def outer(number):
	a = number

    def inner():
    	nonlocal a
        a += 200
        print(a)

    return inner
    
f = outer(100)
f()  # 300
f()  # 500
f()  # 700
f()  # 900

변수에 접근하려면 locals, globals가 있다.
각각 지역변수, 전역변수를 딕셔너리 형태로 저장하고 있고 key값은 str타입으로 저장되어 있다.

def fn(number):
	x = 10
    
    def printt():
    	print("Inner func")
    	print(locals())
    return printt

func = fn(100)

func()
# Inner func
# {'number': 100, 'x': 10, 'printt': <function fn.<locals>.printt at 0x00000193734C1840>}

여기서 알 수 있듯이 함수의 인자는 지역 변수로 들어간다.

globals도 마찬가지이고 파이썬 내부적으로 다음 두 코드는 같은 코드로 볼 수 있다.

a = 100

globals()['a'] = 100
profile
공부!
post-custom-banner

0개의 댓글