일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- terraform
- Shell
- 컨테이너
- BIG-O NOTATION
- 테라폼 기본 문법
- 파이썬
- Django
- terraform 문법
- 빅오노테이션
- test
- DynamoDB
- minikube mac 설치
- zshrc
- docker-compose
- AWS
- 도커
- 도커컴포즈
- docker
- minikube 설치 방법
- server
- python
- iterm2 단축키
- 테라폼 문법
- zsh
- sftp란
- iterm2 shortcuts
- linux
- customize
- Bash
- nosql
- Today
- Total
sklass의 s-class 프로그래밍 blog
__(double underscore) 본문
python에서 _(single underscore)가 변수 앞에 붙으면 private으로 지정하자는 네이밍 룰(naming rule)로 쓰입니다.
하지만 __(double underscore)가 붙는 경우(ex: __variable), 네이밍 룰이라기보다는 python의 문법적인 요소로 생각해야 합니다. 바로 네임 맹글링(name mangling)을 위한 경우로, 파이썬이 해당 변수/함수의 이름을 짓이겨서 바꿔버리는 것을 의미합니다.
맹글링을 당한 변수/함수는 본연의 이름으로 접근할 수 없게됩니다. 아래의 예제를 살펴 보겠습니다.
class TestClass():
def __init__(self):
self.name = "Joseph"
self.__age = 20
test = TestClass()
print(test.name)
>> 'Joseph'
print(test.__age)
>> AttributeError: 'TestClass' object has no attribute '__age'
그렇다면 어떻게 __age에 접근할 수 있을까요?
dir 함수를 까보면 마지막에 name이 보이고 바로 첫 인덱스에 _TestClass__age라는 이름이 보입니다.
print(dir(test))
>> ['_TestClass__age', '__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__', 'name']
print(test._TestClass__age)
>> 20
네임 맹글링(name mangling)을 언제 사용하나요?
파이썬에서 맹글링을 사용하는 상황은 크게 2가지로 볼 수 있습니다.
- 클래스의 속성값을 외부에서 접근하기 힘들게 할 때
- 하위 클래스가 상위 클래스의 속성을 오버라이딩 하는 것을 막을 때
1. 클래스의 속성값을 외부에서 접근하기 힘들게 할 때
이는 위에서 다룬 코드들에 대한 내용으로, TestClass의 age라는 속성을 숨기고 싶을 때 사용합니다. 이는 private과는 조금 다른 개념인데, 이유는 위의 네임 스페이스를 확인하면 알 수 있듯이 __age가 _Test__age로 저장되면서, 아예 접근 불가능하게 만드는 것은 아니고, 접근할 수 있는 변수의 이름이 달라지는 것이라고 이해하면 되겠습니다.
2. 하위 클래스가 상위 클래스의 속성을 오버라이딩 하는 것을 막을 때
클래스가 확장되면서 크기가 커지면 발생할 수 있는 문제인 속성 이름간의 충돌을 막고자 할 때, 특히 오버라이딩을 막고자 할 때 맹글링을 적용시킬 수 있습니다.
class TestClass:
def __init__(self):
self.name = "Joseph"
self.age = 30
class TestClass2(TestClass):
def __init__(self):
super().__init__()
self.name = "Chris"
self.age = 23
test = TestClass2()
print(test.name, man.age)
>> 'Chris, 23'
해당 코드는 아무런 조치를 취하지 않았기 때문에 어떤 제약도 없이 하위 클래스에서 상위 클래스의 속성들을 오버라이딩 할 수 있게 됩니다.
class TestClass:
def __init__(self):
self.name = "Joseph"
self.__age = 30
class TestClass2(TestClass):
def __init__(self):
super().__init__()
self.name = "Chris"
self.__age = 23
test = TestClass2()
print(test.name, test.__age)
>> AttributeError: 'TestClass2' object has no attribute '__age'
하지만 위와 같이 오버라이딩을 막고 싶은 속성(name)에 맹글링을 적용시키면 AttributeError가 발생합니다. 이름이 이제 _TestClass__age와 _TestClass2__age로 변경되었기 때문에, __age 속성을 애초에 가지고 있지 않은 것으로 취급합니다.
'python' 카테고리의 다른 글
shutil (0) | 2021.09.28 |
---|---|
Celery (0) | 2021.09.01 |
@property (0) | 2021.08.26 |
py_src 파일 구조 (0) | 2021.08.26 |
Python Decorator (0) | 2021.08.24 |