[파이썬] 클래스와 객체 구조

I. 클래스와 객체의 관계

가. 클래스 정의

  • 클래스로 객체를 만들어 관계 확인
  • [예제] 클래스 정의
class MyClass(object) :
    pass

print(issubclass(MyClass, object))  # 클래스와 최상위 클래스 객체 상속 관계
print(issubclass(MyClass, type))    # 클래스와 메타클래스 상속 관계
print(isinstance(MyClass, type))    # 클래스는 메타클래스로 생성

[결과]
True
False
True

나. 클래스와 객체 관계 확인

  • 파이썬의 모든 클래스는 메타클래스로 생성되며, 모든 객체도 클래스로 생성
  • [예제] 클래스와 객체 관계 확인
print(isinstance(object, type)) # 모든 클래스는 메타 클래스로 생성
print(isinstance(int, type))    # 정수 클래스도 메타 클래스로 생성

[결과]
True
True

 

II. 객체 내부 검사 (Object Introspection)

  • 클래스와 객체별 별도의 이름공간이 있어 객체는 클래스 상속 관계의 이름공간을 참조
  • [예제] 객체 내부 조사
class MyClass(object) :
    classType = "MyClass"

    def __init__(self, name) :
        self.instanceType = name

c = MyClass("클래스")

print(c)
print(id(c))        # 객체를 레퍼런스 정수로 변환
print(type(c))      # 생성된 객체의 클래스 유형 확인
print(c.__class__) 
print(c.__dict__)   # 객체 내 이름공간 확인

[결과]
<__main__.MyClass object at 0x01191F58>
18423640
<class '__main__.MyClass'>
<class '__main__.MyClass'>
{'instanceType': '클래스'}

 

III. 객체 레퍼런스 비교

  • 객체의 유일성 유지 위해 레퍼런스를 가지며, 유일성 미준수가 발생하는 경우도 있으므로 각은 객체인지 비교 필요
  • [예제] 객체 유일성 점검
a = 100; b = "100"

print(a is b)   # 두 객체의 레퍼런스 비교
print(id(a))    # 객체의 레퍼런스 
print(id(b))

[결과]
False
1596190176
25061792

 

IV. dataclass로 클래스 정의

  • 객체 속성이 많아지면 모두 작성하기 어려우므로 dataclass를 도입하여 타입 힌트 작성해서 객체 속성 자동 생성

가. dataclass로 클래스 생성

  • dataclasses 내 dataclass를 import하여 클래스 생성
  • [예제] dataclass로 클래스 생성
from dataclasses import dataclass

@dataclass
class Person:
    name: str
    age: int

print(Person.__dict__['__init__'])
p = Person("LEE", 20)
print(p.__dict__)
p.sex = "male"
print(p.__dict__)

[결과]
<function __create_fn__.<locals>.__init__ at 0x031FFF58>
{'name': 'LEE', 'age': 20}
{'name': 'LEE', 'age': 20, 'sex': 'male'}

나. dataclass 조정

  • dataclass 내 매개변수를 설정하여 내부 스페셜메소드 생성을 조정
  • [예제] dataclass 매재변수 설정
from dataclasses import dataclass

@dataclass(init=True, repr=False, eq=False, order=False, unsafe_hash=False, frozen=True)
# repr(객체 실행환경에서 출력), eq(객체 비교 함수 생성 결정), order(비교 연산 함수 생성 결정)
# unsafe_hash(__hash__ 함수 생성 결정), fronzen(__setattr, __delattr__ 함수 생성 결정)
class People:
    name: str
    age: int

pp = People("KIM", 30)

print(pp.__dict__)

pp.age = 40     # 객체 속성 값 변경 시 예외 발생
pp.sex = "male" # 새 속성 추가 불가

[결과]
{'name': 'KIM', 'age': 30}
Traceback (most recent call last):
  File "c:\Users\sk\Documents\python.py", line 14, in <module>
    pp.age = 40     # 객체 속성 값 변경 시 예외 발생
  File "<string>", line 4, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field 'age'

 
[참고]

  • 잇플, “한 권으로 개발자가 원하던 파이썬 심화 A to Z”, 2019.11

콘텐츠 사용 시 출처 표기 부탁 드리고, 댓글은 큰 힘이 됩니다^^