파이썬 클래스를 이용하면서 몇 가지 재미난 특징이 있어서 정리해 둡니다.
클래스의 동적 정의
첫 번째는 선언된 클래스라도 중간에 동적으로 멤버 변수 및 멤버 함수를 추가할 수 있다는 점입니다.
뭐 당연한 것인데, 여기에 "isinstance()" 함수가 연관되면 재밌게 됩니다.
아래 예제를 보시면, 특정 클래스에 멤버 변수를 동적으로 추가하는 하였습니다. 멤버 변수를 추가하기 전과 추가한 후의 "isinstance()" 함수의 반환값이 어떻게 될지 추측해 보시기 바랍니다.
class MyClass:
def __init__(self):
self.data = 5
b = MyClass()
print(f'isinstance(b, MyClass) is {isinstance(b, MyClass)}')
print(b.__dict__)
b.data2 = 100
print(b.__dict__)
print(f'isinstance(b, MyClass) is {isinstance(b, MyClass)}')
자유도를 보장하기 위해서인지는 모르겠지만, 결과는 "같다" 입니다. 동적으로 멤버 변수 및 함수가 추가되어도 본질은 같다는 점을 잘 활용하면 다중 상속 등을 하지 않고도 활용할 수 있는 곳이 꾀 될 것 같습니다.
위 예제의 실행 결과는 다음과 같습니다.
isinstance(b, MyClass) is True
{'data': 5}
{'data': 5, 'data2': 100}
isinstance(b, MyClass) is True
private 멤버 변수
파이썬에서 클래스의 private 멤버 변수를 선언하기 위해서는 변수명 앞에 "__"를 붙이도록 되어 있습니다.
class MyClass:
def __init__(self):
self.__data = 5
위와 같이 "__data" private 변수를 선언 후, 외부에서 사용하려고 하면 다음과 같은 오류가 발생합니다.
>>> c = MyClass()
>>> c.__data
Traceback (most recent call last):
File "<pyshell#61>", line 1, in
c.__data
AttributeError: 'MyClass' object has no attribute '__data'
이 때, c 객체의 모든 변수를 출력해 보면 다음과 같습니다.
>>> c.__dict__
{'_MyClass__data': 5}
해당 클래스의 private 변수라고 하더라도 "_<클래스명><private 변수명>"으로 하면 접근이 가능합니다.
>>> c._MyClass__data
5
>>> c.__dict__['_MyClass__data']
5
이는 상속 관계에서도 동일하게 적용됩니다.
class MyClass:
def __init__(self):
self.__data = 5
self.data = 1
class MySubClass(MyClass):
def __init__(self):
super().__init__()
self.__data = 10
d = MySubClass()
print(d.__dict__)
# {'_MyClass__data': 5, 'data': 1, '_MySubClass__data': 10}
부모 클래스와 자식 클래스에서 동일한 "__data" private 멤버 번수를 선언하면 위와 같이 각각 할당이 되고, 외부에서는 "_<클래스명><private 변수명>"으로 각각 접근이 가능합니다.
>>> d._MyClass__data
5
>>> d._MySubClass__data
10
참고자료
- "Private Variables in Python":https://www.tutorialspoint.com/private-variables-in-python
'프로그래밍 > Python' 카테고리의 다른 글
[Python] 윈도우에서 cython_bbox 설치 오류: "ERROR: Failed building wheel for cython_bbox windows" (0) | 2022.05.18 |
---|---|
[Python] 날짜 문자열을 timestamp로 변환하기 (0) | 2022.05.13 |
[Python] numpy.array 배열을 문자열로 변환하는 방법 (0) | 2022.05.02 |
[Python] 윈도우(windows)에서 시그널(signal) 다루기 (0) | 2022.04.20 |
[Python] OpenCV 버전 및 패키지 설치 위치 확인 방법 (0) | 2022.04.04 |