python_string = 'Python Namespace'
python_number = 0
python_boolean = True
python_list = ['python', 'Namespace']
def python_function():
return 'python function'
PythonFunction = python_function
print(python_function())
print(PythonFunction())
#output
python function
python function
PythonFunction = python_function
해당 부분은 함수를 호출할 때와 다르게 괄호를 사용하지 않았는데, 이는 함수를 PythonFunction에 할당했다는 의미이다. def python_function():
return 'python function'
print(python_function)
print(python_function()
#output
<function python_function at 0x107bc1000>
python function
그렇다면 본론으로 와서 python의 NameSpace를 알아보자면, Namespace는 name들의 공간이라고 볼 수 있다.
python 튜토리얼에서는 https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces
네임스페이스는 이름에서 객체로의 매핑입니다.
대부분의 네임스페이스는 현재 Python 사전으로 구현되어 있지만 일반적으로 어떤 방식으로든 눈에 띄지 않으며(성능 제외) 향후 변경될 수 있습니다. 네임스페이스의 예는 다음과 같습니다.
내장 이름 세트(abs() 및 내장 예외 이름과 같은 함수 포함); 모듈의 전역 이름 함수 호출의 로컬 이름. 어떤 의미에서는 객체의 속성 집합도 네임스페이스를 형성합니다.
네임스페이스에 대해 알아야 할 중요한 점은 서로 다른 네임스페이스의 이름 간에는 전혀 관계가 없다는 것입니다.
예를 들어, 두 개의 서로 다른 모듈은 둘 다 혼동 없이 최대화 기능을 정의할 수 있습니다. 모듈 사용자는 모듈 이름 앞에 모듈 이름을 붙여야 합니다.
python의 NameSpace는 '이름(변수명)'과 '객체'를 매핑한 것이라고 볼 수 있다.
python_string = 'Python Namespace'
PythonString = python_string
print(python_string) # Python Namespace
print(PythonString) # Python Namespace
print(id(python_string)) # 4424617056
print(id(PythonString)) # 4424617056
python_string
, PythonString
이라는 변수를 할당했지만 이들 자체가 '문자'는 아니다. 단순히 문자인 객체를 가르킨다.객체 지향 프로그래밍에서의 캡슐화는 변수, 함수들을 한 클래스에 담는 것이다.
python 관점에서 캡슐화를 살펴보면 namespace와 scope
하나의 python module은 독자적인 namespace를 가진다고 할 때, python module은 같은 이름을 가진 함수를 만들 수 없다.
하지만 namespace를 따로 가지고 있는 python module을 만든다면 같은 이름을 가진 함수를 만들어도 상관없다.
def python_function():
python_str = 'Python NameSpace'
print(python_str)
python_function()
print(python_str)
#output
Python NameSpace
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/Users/geonheekim/Desktop/python_study/test_1.ipynb Cell 3 line 6
3 print(python_str)
5 python_function()
----> 6 print(python_str)
NameError: name 'python_str' is not defined
def python_function():
print(python_str)
python_str = 'Python NameSpace~~'
python_function()
예를 들면, python_function에서 python_str을 밖으로 빼놨을 때,
global space로 python_str을 이동시키고, python_function 함수 내에서 python_str을 참조할 때, 잘 참조가 되는 거승ㄹ 볼 수 있다.
local space에서 global space에 접근하는 것은 가능하다.
클래스에서도 MyMac 클래스에 할당한 folders에 접근 할 때
MyMac.folders는 가능하지만 folders는 그냥 접근할 수 없다.
global space에서 folders가 없기 때문이다.
class MyMac:
def __init__(self):
self.folders = 10
my_mac = MyMac()
print(MyMac.folders)
print(folders)
#output
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/Users/geonheekim/Desktop/python_study/test_1.ipynb Cell 3 line 6
3 self.folders = 10
5 my_mac = MyMac()
----> 6 print(MyMac.folders)
7 print(folders)
AttributeError: type object 'MyMac' has no attribute 'folders'
local space에서는 global space를 참조하지만 반대는 그렇지 않듯이 namespace끼리의 의존관계가 존재하는데 이를 LEGB 라고 줄여서 말한다.
L>E>G>B 이렇게 참조가 가능하다는 것인데,
같은 낮은 레벨은 local, 가장 높은 레벨은 built-in 영역이다.
낮은 레벨의 영역은 위 레벨 영역을 참조할 수 있지만 그 반대는 되지 않는다.
global에서 local을 참조할 수 없듯이, built-in에서는 아무 영역도 접근할 수 없는 것이다.
이다.
python_string = 'python NameSpace'
def return_something(subject):
result = python_string + subject
return result
class MyMac:
folders = 10
def describe_mac(self):
result_str = str(self.foders) + 'folders'
return 'There are ' + result + 'on my laptap'
importTest.py
python_string = "python namespace1"
python_number = 1
test.py
import importTest
print(importTest.python_string)
print(importTest.python_number)
#output
python namespace1
1
test.py에서 import importTest를 하면 importTest.py내 존재하는 python_string, python_number에 접근할 수 있지만
바로 python_string, python_number로 사용할 수 없다.
test.py의 Global space에서는 importTest 라는 모듈로 할당된 것이기 때문에 importTest.python_string, importTest.python_number 처럼만 사용 가능하다.
물론 importTest에서 특정한 이름만 가져올 수도 있다.
test.py
from importTest import python_string
print(python_string)
print(python_number)
#output
python namespace1
Traceback (most recent call last):
File "/Users/geonheekim/Desktop/python_study/test.py", line 4, in <module>
print(python_number)
NameError: name 'python_number' is not defined
importTest에서 python_string에 바로 접근할 수 없지만
특정 이름만 가져올 경우에는 바로 pythons_string에 접근할 수 있다.
from importTest import *
을 사용하는 것이다.test.py
from importTest import *
print(python_string)
print(python_number)
#output
python namespace1
1
기본적으로 from importTest import *
을 통해 importTest에 존재하는 모든 이름을 가져올 수 있지만 이를 제어하는 방법도 있다.
importTest.py
__all__ = ["python_string"]
python_string = "python namespace1"
python_number = 1
위 처럼 __all__
안에 python_string
만 둔다면 다른 module에서 importTest.py를 import 할때 python_string만 할당시킬 수 있다.
test.py
from importTest import *
print(python_string)
print(python_number)
#output
python namespace1
Traceback (most recent call last):
File "/Users/geonheekim/Desktop/python_study/test.py", line 4, in <module>
print(python_number)
NameError: name 'python_number' is not defined