2020년 7월 3일
[파이썬] 클래스와 객체 구조
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