Python의 전역 변수는 그렇게 전역적이지 않다
Source: Dev.to
프로그래밍이 1980년대에 있었던 시절을 떠올리면 “전역 변수(global variables)”라는 말은 MBASIC 같은 언어를 연상시킬 수 있습니다. 오늘날 MBASIC을 예시로 들기는 어려운데, 이는 이제 거의 사용되지 않거나 알려지지 않았기 때문입니다. 대신, 많은 시스템에서 기본 쉘 스크립팅 언어로 쓰이는 GNU Bash를 사용해 전통적인 전역 변수가 어떤 모습이었는지 보여드리겠습니다. (일부는 Fortran II를 떠올릴 수도 있겠지만, 저는 그에 익숙하지 않습니다.)
Bash 예시
a.bash
#!/bin/bash
. ./b.bash
. ./c.bash
. ./d.bash
init
print_count
inc
print_count
b.bash
inc() {
counter=$((counter + 1))
}
c.bash
print_count() {
echo $counter
}
d.bash
init() {
counter=1
}
Python 예시
a.py
import c, b, d
d.init()
c.print_count()
b.inc()
c.print_count()
b.py
import d
def inc():
d.counter += 1
c.py
import d
def print_count():
print(d.counter)
d.py
def init():
global counter
counter = 1
주요 차이점
보시다시피 Bash에서 전역 변수는 파일 간에 진정한 전역성을 가집니다. 반면 Python에서는 전역 변수가 모듈(파일) 내부에서만 전역입니다. Bash에서는 전역 변수를 변경할 때 특별한 구문이 필요 없지만, Python에서는 모듈 수준 변수를 수정하려면 함수 안에서 global을 명시적으로 선언해야 합니다.
따라서 두 언어 모두 “전역 변수”라고 부르지만, Python의 전역 변수는 모듈에 한정된 스코프를 가집니다. 이는 다른 모듈의 변수와 충돌하지 않으며, 개발자가 모듈당 하나의 클래스를 사용한다면 Python 전역 변수는 클래스 변수와 매우 흡사하게 동작합니다. 또한 Python 함수 내부에서 변수 할당은 기본적으로 로컬이기 때문에, 명시적으로 global을 선언하지 않는 한 전역 상태를 우연히 변경하는 일을 방지합니다.
요약하면, Bash나 MBASIC 같은 전통적인 언어에서 전역 변수에 대해 주의하라는 조언은 Python에서는 더 이상 그대로 적용되지 않을 수 있습니다. 따라서 과거의 조언에 따라 전역 변수를 무조건 배제하기보다는, 실제 사용 사례를 신중히 평가하는 것이 좋습니다.