supergravity
파이썬 - namespaces, scopes 본문
0. 시작
namespace와 scope개념은 파이썬의 클래스의 작동원리를 이해하는데 꼭! 필요한 요소입니다.
초급자의 경우 다음으로 미뤄도 괜찮은 일이지만.
파이썬 고수가 되기 원한다면 중요한 개념이니 빡세게 배워 봅시다.
이 튜토리얼은 파이썬 공식문서를 쉽게 설명하려고 노력했습니다.
그러면 시작해 봅시다.
1. namespace
1.1 정의
파이썬 공식문서에서 namespace의 정의를 찾아보면 "name 집합에서 object집합으로 가는 함수"로 정의되어 있습니다.
이게 도대체 무슨 말일까요?
파이썬에서 name은 변수를 말하고 object는 메모리에 올려진 데이터 또는 코드를 말합니다.
그래서 name에서 object로 가는 함수는 변수와 데이터를 연결한다로 해석할 수 있습니다.
컴퓨터 공학적인 용어로 name을 object의 reference라고 불르기도 합니다.
파이썬 버전 3.9에서 대부분의 namespace는 파이썬 딕셔너리 자료형을 이용해서 구현되었습니다.
이러한 구현은 파이썬 성능 최적화가 되지 않은 구현이라 나중에 변경될 수도 있다고 합니다.
미래는 모르는 일이지만 파이썬에서 성능 최적화를 하기 위해 C 코드로 작성하곤 합니다.
그래서 C로 다시 구현하지 않을까 생각이 됩니다.
1.2 namespace 사용법
namespace는 대부분 파이썬 딕셔너리로 구현되어 있어 key와 value를 가집니다.
key는 object의 reference이고 name이라 말하기도 합니다.
value는 object의 메모리 위치를 나타 냅다.
namespace를 사용하는 방법은 간단합니다.
name(key)를 이용하여 사용하면 됩니다.
만약 object가 attribute나 method가 존재한다면
점을 이용하여 접근할 수 있습니다.
예를 들어 { 'z ' : <module in 1141141414> }가 namespace라고 가정해봅시다.
그리고 object z의 attribute가 존재하고 이 attribute에 대한 reference 가 real이면
z.real 접근하여 사용이 가능합니다.
1.1 실험
보다 나은 이해를 위해 namespace의 예를 찾아봅시다.
우선 아래의 코드를 실행시켜 봅시다.
실험은 구글 드라이브에서 무료로 사용할 수 있는 Colab을 이용합니다.
globals()는 파이썬의 글로벌 네임스페이스 풀어 설명해서 글로벌 프레임에 저장되어 있는 오브잭트의 레퍼런스입니다.
이 내용은 뒤에 계속 다룰 것이니 이해가 되지 않더라도 걱정하지 말자. 출력돼서 나오는 내용이 namespace 정의에 부합된다는 사실만 이해하면 됩니다.
위의 코드 결과에서 파란 블록은 파이썬 내장 함수의 namespace를 나타내는 부분입니다.
그다음 dis모듈을 추가하고 임포트하고 실행해 봅시다.
파란색 박스를 보면 딕셔너리에 key가 dis이고 value가 파이썬 파일 위치를 나타내는 object가 추가된 것을 볼 수 있습니다.
파이썬에서 dis를 임포트하고 실행하게 되면 추가된 모듈은 글로벌 네임스페이스에 추가됩니다.
그러면 아래와 같이 key(모듈, dis)과 점(.)을 이용해 사용할 수 있게 됩니다.
1.2에서도 언급을 했지만 파이썬에서 점은 object의 attribute 또는 method에 접근할 때 사용하는 문법입니다.
dis 모듈을 파이썬 코드 내부를 보여주는 모듈입니다.
이에 대해서 몰라도 되지만 모듈 이름과 점을 이용하여 함수를 사용할 수 있다는 사실은 알아야 합니다.
이제 test함수가 정의된 상태에서 globals()를 확인해 봅시다.
test 가 추가된 것을 볼 수 있습니다.
dis와 마찬가지로 key값을 이용하여 코드를 작성할 수 있습니다.
여기서 __main__. test라고 되어 있습니다.
이건 또 뭔 말일까?
모듈을 임포트 해서 사용하는 경우는 파이썬의 경로를 나타내는 object가 value에 있었습니다.
이와 같은 맥락으로 __main__이란 뜻은 현재 실행되고 있는 파이썬 파일을 말합니다.
이 또한 globals()에 저장되어 있는데 "__name__" : "__main__"부분입니다.
재미있는 부분은 __name__도 key이기 때문에 이를 코드에서 사용할 수 있습니다.
이를 활용하여 파이썬 파일이 모듈로 실행될 때와 main으로 실행될 때를 구분할 수 있습니다.
이에 대한 내용은 여기에서 찾아볼 수 있습니다. 클릭!
1.4 namespace 라이프 타임
namespace는 종류에 따라 실행되는 시간과 종료되는 시간이 다릅니다.
위에서 본 바와 같이 global namespace 같은 경우 built-in 함수(names)가 존재합니다.
built-in 함수 같은 경우 파이썬 인터프리터가 시작될 때 생성이 되고 프로그램이 종료될 때까지 메모리에서 삭제되지 않습니다.
global namespace에 저장되는 모듈 같은 경우 모듈이 정의될 때 namespace가 생성이 되고 종료될 때까지 삭제되지 않습니다.
global namespace 말고도 local namespace가 있습니다.
local namespace의 경우 함수를 실행시키기 위해 존재합니다.
그래서 local namespace는 함수가 실행이 될 때 생성이 되고 함수가 끝날 때 같이 제거됩니다.
재귀함수의 경우 각각 독립된 local namespace가 존재합니다.
이해를 위해 예를 들어 봅시다.
local_test를 정의하고 실행하는 코드입니다.
프로그램을 실행하게 되면 built_in 함수를 담은 built-in namespace가 global namespace에 저장이 됩니다.
print() 함수는 built-in namespace에 포함돼 있어 이때 저장이 됩니다.
인터프리터가 def local_test()를 인지하고 global namespace에 저장을 합니다.
인터프리터가 local_test() 구문을 만나면 local_test()를 실행하기 위해 독립된 메모리를 확보합니다.
그리고 local namespace를 생성합니다.
local namespace에 a를 추가합니다.
a를 찾기 위해 local namespcae를 탐색합니다.
a를 발견합니다.
print 구문을 만나면 print가 local namespace에 존재하는지 확인합니다.
존재하지 않으면 global namespace에서 확인합니다.
global namespace의 built-in 안에서 print를 발견합니다.
print와 a에 해당하는 value를 이용하여 print(a)를 실행합니다.
실행 시 print()의 local namespce가 같이 생성이 됩니다.
화면에 3이 출력이 되면 print함수의 local namespace와
local_test의 local namespace를 차례로 삭제합니다.
built-in namespace를 구체화시키기 위한 예제도 살펴봅시다.
__builtin__은 globals()에 key(name)에 존재함으로 구문을 작성할 수 있습니다.
또한 __builtin__에 저장이 되어있는 name에 접근하기 위해서 점을 이용합니다.
파이썬에서는 builtin의 경우 __builtin__을 작성하지 않고도 사용할 수 있는 기능을 제공하고 있습니다.
2. scope
스코프는 변수 또는 함수가 사용될 수 있는 범위를 말합니다.
스코프는 namespace 라이프타임과 밀접한 관련이 있습니다.
built-in namespace, global namespcae, local namespace의 라이프 타임을 크리스탈 클리어하게 이해하고 있으면
scope는 거저먹기입니다.
2.1 scope의 종류
스코프에는 총 4가지가 존재합니다.
하나씩 알아봅시다.
Local Scope
함수가 1개일 때 local namespace는 함수 실행과 동시에 생성이 됩니다.
그리고 함수 내에 있는 변수들이 local namespace에 저장이 됩니다.
함수가 종료될 때 local namespace는 삭제됩니다.
그래서 함수 내에 존재하는 변수들은 함수 밖에서 사용이 불가합니다.
이렇게 변수를 밖에서 사용하지 못하는 변수의 scope를 Local Scope라고 합니다.
Enclosed Scop
함수 안에 함수가 정의되어 있을 때 변수에서 나타나는 현상입니다.
함수 안에 함수를 정의했다고 생각을 해봅시다.
여기서 밖의 함수를 fuc-0 안의 함수를 fuc-1라고 생각해봅시다.
fuc-0 함수가 실행이 되면 fuc-0 local namespace가 생성됩니다.
그리고 한 줄씩 진행하다.
fuc-1 함수를 만나면 fuc-1가 호출되면 fuc-1 local namespace를 생성합니다.
fuc-1 호출이 끝나면 fuc-1 local namespace가 종류 됩니다.
fuc-0 함수가 종료되고 fuc-0 local namespace가 삭제됩니다.
이러한 상황에서 fuc-0 namespace는 fuc-1 함수가 실행되고 있을 때 살아있습니다!
그래서 fuc-1 함수에서 fuc-0 namespace의 정보를 이용하는 것이 가능합니다.
이때 fuc-0 namespace의 변수들은 Enclosed Scop를 가진다고 말합니다.
Global Scope
파이썬 파일에 해당하는 스코프입니다.
그래서 파일 어디서나 접근 가능합니다.
파이썬 파일 실행 시 global namespace가 생성이 됩니다.
종료 될 때 까지 globla namespace는 제거되지 않습니다.
그렇기에 어디에서나 global namespace의 변수나 함수를 사용할 수 있습니다.
Built-in Scope
built-in scope는 파이썬 내장 함수들이 스코프입니다.
파이썬 인터프리터가 실행될 때 생성이 됩니다.
global namespace보다 먼저 실행이 되며 global namespace가 생성되면
이에 name이 '__builtin__'의 형태로 추가됩니다.
__builtin__인은 파이썬 딕셔너리 형태의 오브잭트 built-in namespace의 레퍼런스(name)입니다.
https://velog.io/@inyong_pang/Python-Scope-8yk42kog5x
'콘텐츠 > 파이썬 -구조' 카테고리의 다른 글
파이썬 - __main__ (0) | 2021.09.08 |
---|---|
cython , cpython, python ? (0) | 2021.09.04 |
파이썬 - 메모리 관리와 좋은 습관 (9) | 2021.08.31 |
파이썬 - 스트링을 메모리에 어떻게 저장할까? (2) | 2021.08.29 |