반응형
예시 1
_list = [1, 2, 3, 4]
def sum_all():
sum_val = 0
for elem in _list:
sum_val += elem
return sum_val
total_sum = sum_all()
print(total_sum)
print(sum_val)
10
NameError: name 'sum_val' is not defined
- 전역 변수는 굳이 인자로 넘기지 않아도 함수 내에서 잘 작동한다. 즉, 전역 변수는 어디에서나 쓸 수 있다.
- 지역 변수는 내부 Scope를 벗어나면 증발하여 더 이상 접근할 수 없다. 즉, 지역 변수는 어디에서나 쓸 수 없다.
예시 2
코드 1.
_list = [1, 2, 3, 4]
def modify():
_list[0] = 10
modify()
for elem in _list:
print(elem, end=" ")
10 2 3 4
- list는 mutable한 객체이므로, 전역 변수로 선언되었을 때 함수 내부에서 값을 참조하고 수정해도 원본에 반영된다.
- 위의 코드에서 modify() 함수 내부의 _list 변수는 외부에 선언된 전역 변수 _list로 인식된다.
코드 2.
_list = [1, 2, 3, 4]
def modify():
_list = [5, 6, 7, 8]
modify()
for elem in _list:
print(elem, end=" ")
1 2 3 4
- 반면, 위의 코드에선 modify() 함수 내부의 _list가 재정의 되었으므로, python에선 이를 새로운 지역 변수로 인식한다.
- 따라서 modify() 함수가 끝나는 순간 (새로 생성됐던) 함수 내부의 _list 객체는 소멸하고, 외부에 선언된 전역 변수 _list만 남게 된다.
- 만일 modify() 함수 내부의 _list를 전역 변수로 인식하도록 하려면, 다음처럼 함수 안에 global 표식을 해주어야 한다.
_list = [1, 2, 3, 4]
def modify():
global _list
_list = [5, 6, 7, 8]
modify()
for elem in _list:
print(elem, end=" ")
5 6 7 8
- 원래 원칙은, 전역 변수를 함수 내에서 쓰려면 함수 안에 global 표식을 해줘야 한다.
- 하지만 모르거나 귀찮아서 보통 잘 쓰지 않는다. 평소에 안 써도 무방하다.
예시 3
코드 1.
num = 10
def modify():
print(num)
modify()
10
- 전역 변수를 함수 내부에서 값을 끌어다 쓰는 것은 모두 허용된다.
코드 2.
num = 10
def modify():
num = 5
print(num)
modify()
print(num)
5
10
- 10, 5는 immutable한 객체이다.
- 따라서 함수 외부와 내부에 같은 이름의 변수 num을 선언하면
- 함수 내부에서 num을 출력할 땐 지역 변수 num의 값 5를 출력하고 (내부 변수가 외부 변수를 가림)
- 함수 밖에서 num을 출력할 땐 전역 변수의 num 값 10을 출력하는 것이다.
코드 3.
num = 10
def modify():
num += 5
modify()
print(num)
UnboundLocalError: local variable 'num' referenced before assignment
- 이 코드에선 왜 이러한 에러가 발생하는지 이해해보자.
- num += 5 는 num = num + 5와 동일한 코드이다.
- 이를 반영하여 코드를 다시 작성하면 아래와 같다.
num = 10
def modify():
num = num + 5
(1번) (2번)
modify()
print(num)
- modify() 함수 내의 (1번) num이 새롭게 정의되었으므로 이는 New 지역 변수로 인식된다.
- 따라서 (2번) num도, 전역 변수의 num이 아닌, 새로운 지역 변수로 인식된다.
- 이 지역 변수 (2번) num은 값이 아직 할당이 되지 않았기 때문에 위와 같은 에러가 발생하는 것이다.
- 이를 해결하고자 한다면, 함수 내에 global 표식을 붙여 modify() 함수 내 num을 전역 변수 num으로 인식되도록 해주면 된다.
num = 10
def modify():
global num
num += 5
modify()
print(num)
15
정리
✨- 전역 변수로 선언된 immutable 객체를 함수 내에서 바꾸고 더하는 작업을 하려면, global 표식을 해주어야 한다.
- 전역 변수로 선언된 mutable 객체를 함수 내에서 바꾸고 더하는 작업을 하려면, 객체 특성 상 그냥 갖다 써도 상관 없다.
- 대신 함수 내에서 전역 변수와 같은 이름으로 변수를 재정의 한다면, immutable 객체든 mutable 객체든 재정의된 변수는 새로운 지역 변수로 인식된다. 이렇게 되기 싫으면 global 표식을 해주면 된다.
(+) 참조 가능한 값이 여러 가지일 때
a, b = 10, 20
def modify(a, b):
print(a, b) # (1번)
print_a_and_b()
a, b = b, a
print(a, b)
def print_a_and_b():
print(a, b) # (2번)
modify(50, 60)
print_a_and_b()
50 60
10 20
60 50
10 20
- (1번)에서의 a, b는 전역 변수의 a, b (10, 20)를 참조하는 것도 가능하고 인자 값 (50, 60)을 참조하는 것도 가능하다.
- 이렇게 참조할 수 있는 값이 여러 가지일 땐, 가장 가까이에 있는 값을 참조한다.
- 즉, (1번)에서 a는 50을 가리키고, b는 60을 가리킨다.
- (2번)의 경우, a, b는 전역 변수 a, b밖에 참조할 값이 없으므로 각각 10, 20을 가리킨다.
참고 자료 : Code Tree, Python - 변수의 특징(mutable, immutable)과 전달(Call by ?) (개인 블로그)
반응형
'◼ IT Etc. > Python' 카테고리의 다른 글
[Python] 조건문 (0) | 2023.01.21 |
---|---|
[Python] 사칙연산을 위한 연산자 (0) | 2023.01.21 |
[Python] Call by Assignment 이해하기 (0) | 2022.04.03 |
[Python] 파이썬 입력 함수 input 사용법 정리 (0) | 2022.03.17 |
[Python] 파이썬 출력 함수 print 사용법 정리 (0) | 2022.03.16 |