개발을 하다 보니, 자주 쓰는 모듈의 객체가 정의된 클래스들을 보면
언더스코어('_') 와 더블 언더스코어('__') 가 메소드 명 앞에 쓰이는 것을 볼 수 있다.
이 차이를 좀 제대로 정리하고 싶어서 기록한다.
underScore.py
v1 = "variable1"
v2 = "variable2"
_v3 = "variable3"
test.py 에서 underScore 모듈을 import 한후 dir()
함수를 이용해서, 현재 네임스페이스에 정의된 모든 이름을 나열해본다.
네임스페이스 ? => https://velog.io/@heyggun/python-NameSpace%EB%84%A4%EC%9E%84%EC%8A%A4%ED%8E%98%EC%9D%B4%EC%8A%A4
그래서 dir로 현재 네임스페이스에 정의된 모든 이름을 나열해보면,
test.py
from underScore import *
print(dir())
# output
['__annotations__', '__builtins__', '__cached__', '__doc__',
'__file__', '__loader__','__name__', '__package__', '__spec__',
'v1', 'v2']
가 나온다. 언더 스코어('_')를 붙인 변수 _v3
는 네임스페이스에서 빠져있다.
그러나, 해당 모듈을 import 하면 해당 변수 _v3
를 로드해올 수 있다.
test.py
import underScore
from underScore import *
print(dir())
print(underScore.v1)
print(underScore.v2)
print(underScore._v3)
# output
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'underScore', 'v1', 'v2']
variable1
variable2
variable3
직접 가져다 쓰는 것은 가능한데 접근 제한을 권유 하지만 강제하지는 않는다. 언더스코어를 붙이는 것은 일종의 컨벤션(convention)이다.
컨벤션(Convention) : 일종의 관례 또는 약속
프로그래밍에서 컨벤션은 코드를 작성하거나 구성할 때 따르는 일련의 규칙이다.
DoubleUnderScore.py
class MyClass:
def __init__(self):
self.__privateVar = "Double Under Score"
self._semiprivateVar = "single Under Score"
그리고 test.py 파일에서 해당 클래스를 import 하고
싱글 언더스코어로 정의한 _semiprivateVar
는 접근이 가능하다.
test.py
from DoubleUnderScore import *
myclass = MyClass()
print(myclass._semiprivateVar)
#output
single Under Score
그러나, 더블 언더스코어를 사용하면 접근 자체가 불가하다.
test.py
from DoubleUnderScore import *
myclass = MyClass()
print(dir(myclass))
print(myclass._semiprivateVar)
print(myclass.__privateVar)
#output
['_MyClass__privateVar', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_semiprivateVar']
single Under Score
Traceback (most recent call last):
File "/Users/geonheekim/Desktop/langchain_note/test.py", line 6, in <module>
print(myclass.__privateVar)
AttributeError: 'MyClass' object has no attribute '__privateVar'. Did you mean: '_semiprivateVar'?
_변수명
을 _클래스명__변수명
으로 치환한다.즉, MyClass의 __privatVar
에 접근하려면 치환된 변수명을 알아야 하는데, 치환된 변수명은 위의 규칙에 따라 _MyClass__privateVar
와 같이 변한다.
즉, test.py에서 더블 스코어로 할당한 변수에 접근하려면 다음과 같다.
test.py
from DoubleUnderScore import *
myclass = MyClass()
print(dir(myclass))
print(myclass._MyClass_privateVar)
print(myclass._semiprivateVar)
# output
['_MyClass__privateVar', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_semiprivateVar']
Double Under Score
single Under Score