Python은 Java와 달리 접근 제한 속성(private)을 강제하지 않습니다.
하지만 private처럼의 사용을 흉내내기 위해 언더스코어(_) 또는 더블언더스코어(__)을 사용하는데
이번 포스팅에서는 둘의 차이가 무엇인지 살펴보겠습니다.
1. 언더스코어(_, Single Underscore)
언더스코어를 사용한 변수는 프로그래머한테 private처럼 사용할테니 외부에서 접근하지 말라는 의미입니다.
이 경우, 해당 모듈을 외부에서 참조할 경우 변수가 없는 것처럼 보이나 실제로는 접근 가능합니다.
무슨 말이냐면 예를 들어 살펴보겠습니다.
under_score_test.py
var1 = "hi_there1"
var2 = "hi_there2"
_var3 = "hi_there3"
test.py
from under_score_test import *
print(dir(under_score_test))
# ['__builtins__', '__cached__', '__doc__', ... 중략 , 'var1', 'var2']
under_score_test.py를 만들고 이를 test.py에서 import한 결과
언더스코어를 붙인 변수 _var3은 import에서 빠졌습니다.
하지만 직접 가져다 쓰는 것은 가능합니다.
접근제한을 권유하되 강제하진 않습니다. 언더스코어를 붙인다는 것은 그저 일종의 컨벤션입니다.
import under_score_test
print(dir(under_score_test))
print(under_score_test._var3) # hi_there3
2. 더블언더스코어(__, Double Underscore)
더블언더스코어(__)도 마찬가지로 private를 구현하기 위해 사용합니다.
예제를 들어보겠습니다.
MyClass.py
class MyClass():
def __init__(self):
self.__superprivate = "Hello"
self._semiprivate = ", world!"
test.py
from MyClass import *
mc = MyClass()
print(mc._semiprivate) # , world!
싱글언더스코어를 사용한 변수 _semiprivate는 접근이 가능합니다.
다만 더블언더스코어를 사용하면 접근 자체가 불가합니다.
from MyClass import *
mc = MyClass()
print(dir(mc))
print(mc._semiprivate)
print(mc.__superprivate)
# error AttributeError: 'MyClass' object has no attribute '__superprivate'
더블언더스코어 사용은 애초에 클래스내 비슷한 이름들끼리 충돌을 방지하기 위함입니다.
더블언더스코어를 사용함으로써 Python 인터프리터한테 해당 변수를 다른 이름으로 치환하라고 알려줍니다.
이 규칙은 어디서든 동일하게 적용되는데 '_변수명'을 '__클래스명__변수명'으로 치환합니다.
그러므로 예제에서 MyClass에 __superprivate에 접근하기 위해서는 치환된 변수명을 알아야합니다.
치환된 변수명은 위의 규칙에 따라 __MyClass__superprivate와 같이 변합니다.
따라서 test.py에서 해당 변수에 접근하려면 다음과 같이 합니다.
from MyClass import *
mc = MyClass()
print(dir(mc))
print(mc._MyClass__superprivate) # Hello
print(mc._semiprivate) # , world!
3. 참조
'파이썬 > 기초문법' 카테고리의 다른 글
Python으로 문자 치환하기 str.translate (0) | 2020.09.20 |
---|---|
Python Global Interpreter Lock (GIL) 참조하기 좋은 글 (0) | 2020.05.24 |
Python 인터프리터 vs 컴파일러 / Is Python interpreted or compiled? Yes 번역 (0) | 2020.04.20 |
Python if __name__ == '__main__': 에 대한 이해 / Python __name__ (0) | 2020.04.18 |
Python namespace에 대한 이해 / Python 네임스페이스 (0) | 2020.04.15 |
댓글