프로그래밍/Python

[Python] 객체의 속성 관련 정리

채윤아빠 2022. 5. 28. 08:48
728x90
반응형


파이썬에서는 선언된 클래스라도 중간에 동적으로 멤버 변수 및 멤버 함수를 추가할 수 있습니다. 그래서 다음과 같은 코드도 아무런 이상없이 동작합니다.

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)}')

그러나, 다음 예제를 보시면, 'object' 클래스에 대한 객체는 멤버 변수를 추가하려고 하면, "AttributeError: 'object' object has no attribute" 오류가 발생합니다. 물론 'object' 클래스 자체를 사용할 일이 거의 없기는 할것입니다. 그리고 'dict'형과 유사하게 할당하는 것도 "TypeError: 'object' object does not support item assignment" 오류가 발생합니다.

a = object()
"""
a.recording_path = './video' # 'object' 클래스에 대한 객체는 멤버 변수 추가 불가
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in 
    a.recording_path = './video'
AttributeError: 'object' object has no attribute 'recording_path'

a['recording_path'] = './video'
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in 
    a['recording_path'] = './video'
TypeError: 'object' object does not support item assignment
"""
print(a) # 


class A:
    pass

a = A()
a.recording_path = './video' # 동적 클래스 멤버 변수 추가
print(a) # <__main__.A object at 0x000002D98D738190>
print(a.recording_path) # './video'


class B(object):
    pass

b = B()
b.recording_path = './video'
print(b) # <__main__.B object at 0x000002D98D738370>
print(b.recording_path) # './video'
"""
b['recording_path'] = './video'
Traceback (most recent call last):
  File "<pyshell#26>", line 1, in 
    b['recording_path'] = './video'
TypeError: 'B' object does not support item assignment
"""
print(b.__getattribute__('recording_path')) # './video'
"""
print(b.__getattribute__('recording_path1'))
Traceback (most recent call last):
  File "<pyshell#28>", line 1, in 
    b.__getattribute__('recording_path1')
AttributeError: 'B' object has no attribute 'recording_path1'
"""
print(hasattr(b, 'recording_path')) # True
print(hasattr(b, 'recording_path1')) # False

전체 실행결과는 다음가 같습니다.

<__main__.A object at 0x000002107C8E2FD0>
./video
<__main__.B object at 0x000002107C8E2F70>
./video
./video
True
False

hasattr() built-in 함수에 대한 도움말은 다음과 같습니다.

help(hasattr)
Help on built-in function hasattr in module builtins:

hasattr(obj, name, /)
    Return whether the object has an attribute with the given name.

    This is done by calling getattr(obj, name) and catching AttributeError.

특정 객체에 동적 멤버 변수를 다룰 때는 해당 객체에 얻고자하는 속성이 존재하고 있는지 먼저 hasattr() 함수를 이용하여 확인 후, getattr() 함수나 객체의 __getattribute__() 함수를 이용해야 합니다.