
scope는 어떤 객체(함수, 변수 등)가 유요한 범위를 뜻한다. 범위를 벗어나면 해당 객체는 사용될 수 없다.
Python에서 scope은 항상 객체가 선언된 지점에서 위로는 상위 객체까지 아래로는 모든 하위 객체들과 그 안에서까지가 범위다.
scope는 총 4가지 범위가 있다
built-in scope이 가장 광범위하다.
Local Scope을 가지고 있는 변수나 함수 혹은 객체는 특정 범위에서만 유효하다. 보통 함수에 선언된 변수나 함수가 local scope을 가지고 있고, 이런 변수들은 해당 함수 안에서만 유효하다.

coffee는my_function함수 안에 있는 local scope 변수다. 즉my_function함수 밖에서print(coffee)를 시도할 시NameError가 나오는 것이다.
Enclosing Scope는 중첩함수가 있을 떄 적용되는 scope이다. 부모 함수에서 선언된 변수는 중첩함수 안에서도 유효한 범위를 가지고 있다.

my_function함수 안에other_function이라는 함수를 선언했다. 여기서water는other_function함수 안에서만 쓸 수는 local scope다. 따라서print(water)는other_function함수 밖에서 선언할 수 없으므로NameError가 뜬 것이다.
그러나
coffee는other_function부모 함수인my_function에서 선언된 변수임으로 enclosing scope으로 사용할 수 있다. 따라서 7번 줄에 선언한print(f'{water}, {coffee}')는 300ml, 500ml으로 정상 출력된다.
Global scope는 함수 안에서 선언된 변수, 함수가 아닌 함수 밖에서 선언한다. Global scope는 가장 바깥쪽에서 선언되므로 해당 파일에서 선언된 지점 아래로는 모두 쓸 수 있다.

milk는 global scope이기 때문에 ``other_function``` 속에도 적용할 수 있다.
가장 광점위한 scope로 파이썬 안에 내장되어있는 파이썬이 제공하는 함수, 속성들이 built-in scope를 가지고 있다. 즉 따로 선언을 안해도 모든 파이썬 파일에서 유효한 범위를 가지고 있다.
len()함수는 built-in scope이다.
파이썬은 변수나 함수의 정의를 찾을 때 다음 순서의 Scope들 안에서 찾는다:
local scope -> enclosed scope -> global scope -> built-in scope
가장 좁은 유효범위부터 시작해, 가장 넓은 범위로 나아간다. 만약 동일한 이름의 변수들이 서로 다른 scope 안에서 선언이 돼도 더 좁은 범위에 있는 변수를 가리는 shadowing 효과가 나타난다.

my_function함수 안에 있는milk`` 변수가 아닌 global scope으로 선언된milk``` 변수값이 출력된다.
함수 안에서 전역 변수의 값을 변경하려면 global 키워드를 사용하면 된다.
x = 10 # 전역 변수
def foo():
global x # 전역 변수 x를 사용하겠다고 설정
x = 20 # x는 전역 변수
print(x) # 전역 변수 출력
foo()
print(x) # 전역 변수 출력
출력:
20
20
만약 전역 변수가 없을 때 함수 안에서 global을 사용하면 해당 변수는 전역 변수가 된다:
# 전역 변수 x가 없는 상태
def foo():
global x # x를 전역 변수로 만듦
x = 20 # x는 전역 변수
print(x) # 전역 변수 출력
foo()
print(x) # 전역 변수 출력
파이썬에서 변수는 네임스페이스(이름공간)에 저장된다. locals() 함수를 통해 네임스페이스를 딕셔너리 형태로 출력할 수 있다.

마지막 딕셔너리 요소로 추가됐다!
Reference:
https://dojang.io/mod/page/view.php?id=2364