python을 포함한 대부분의 언어에는
변수 유효 범위
라는 개념이 있음
변수가 선언된 위치나 키워드에 따라 변수를 사용할 수 있는 범위가 달라지는데,
이를 변수 유효 범위 혹은 variable scope라고 부른다.
파이썬에서 변수는 유효 범위에 따라 두 가지로 나뉜다.
- 지역 변수(local variable) : 함수 내부에서 선언되며 다른 함수에 영향을 끼치지 않음
- 전역 변수(global variable) : 함수 밖에서 선언되며 어디서든 접근할 수 있음
🐍 지역 변수(local variable)
지역 변수로 선언된 변수는 global 키워드를 사용해 전역 변수로 재선언할 수 있다.
def func1():
number = 10 # 함수 내에서 number라는 지역 변수를 선언
def func2():
print(number) # func1에서 생성된 지역 변수는 funt2에서 접근할 수 없다.
func1()
func2()
"""
NameError: name 'number' is not defined
"""
🐍 전역 변수(global variable)
일단 선언만 해주면 함수 밖, 안 어디서든 자유롭게 접근할 수 있다.
number = 10 # 함수 밖에서 number라는 전역 변수 생성
def func():
print(number) # 전역 변수는 자유롭게 접근할 수 있다.
func() # 함수를 실행하면 10이 정상적으로 출력된다.
그럼 무조건 전역 변수로 선언하는 게 좋은거 아닌가
라고 생각할 수 있지만 문제점도 있다.
🐍 전역 변수 사용 시 주의할 점
1) 함수 내에서 전역 변수의 값을 바꾸려 할 경우
number = 10
def func():
number = 5 # 전역 변수의 값이 바뀌는 것이 아닌, 지역 변수로 다시 선언됨
func()
print(number) # 10
# 함수 내에서 재할당 된 지역 변수는 전역 변수에 영향을 끼치지 않음
2) 전역 변수 사용과 지역 변수 할당을 같이 하는 경우
number = 10
# 전역 변수인 10을 출력하고 지역 변수로 다시 선언하는 코드 작성
def func():
print(number)
number = 5
func()
# 실행시켜 보면 에러가 발생함
"""
UnboundLocalError: local variable 'number' referenced before assignment
"""
📌 왜 UnboundLocalError가 발생할까?
함수 내부에서 전역 변수와 동일한 이름으로 지역 변수를 할당할 경우,
함수에서는 해당 변수를 지역 변수로 간주한다.
즉, number 는 이제 전역 변수가 아니라 지역 변수가 되었음.
따라서 func() 함수 내의 print(number) 에서는
아랫줄에서 number 지역 변수가 선언되기 이전에 출력을 시도한 셈.
3) 함수 내에서 전역 변수의 값을 바꾸려면?
test = 123
def func():
test = 456
print(test)
def func2():
print(test)
func() # 456
func2() # 123
global 키워드를 사용해 함수 내에서 전역 변수를 다시 할당할 수 있긴함
number = 10
def func():
global number # 함수에서 number 변수를 다시 할당할 수 있도록 해줌
number = 5 # global 키워드를 사용했기 때문에 전역 변수의 값이 변경됨
print(number)
func() # 5
근데 권장하지는 않음.
📌 전역 변수를 권장하지 않는 이유
파이썬을 포함한 많은 프로그래밍 언어에서 전역 변수를 남용하는 것은 권장하지 않음.
코드가 길어질수록 전역 변수로 선언 된 값은 어디서 값이 변했는지 추적하기 어렵고,
문제가 생겼을 때 디버깅을 하기 어려워지기 때문.
이와 같은 이유로 PIE = 3.14와 같은 전역 상수를 선언하는 것을 제외하면
전역 변수를 사용하지 않는 것이 좋은 코드를 만드는 방법이다.
더 자세한 참고
https://stackoverflow.com/questions/19158339/why-are-global-variables-evil
따라서
다른 함수에서 사용된 결과값을 가져와서 사용하고 싶다면
변수로 저장하고 사용하는 게 아니라 return 을 사용하는 것을 권장
test = 123
def func():
return 456
def func2(value):
print(value)
result = func()
func2(result) # 456