내장 자료형의 상속은 까다롭다

매일 공부(ML)·2023년 2월 13일
0

Fluent Python

목록 보기
81/130

객체지향 상용구

내장 자료형 상속과 다중 상속

이번주는 Tkinter GUI 툴킷과 장고 웹 프레임워크라는 2개의 중요 파이썬 프로젝트를 이용해서 다중 상속을 설명한다.

내장 자료형의 상속은 까다롭다.

파이썬 2.2이전까지는 list나 dict등 내장 자료혀을 사용할 수 없지만, 2.2 버전 이후부터는 내장 자료형을 상속할 수는 있었으나 C언어로 작성된 내장 클래스의 코드는 사용자가 오버라이드한 코드를 호출하지 않으므로 상당한 주의가 필요하다.


공식적으로 CPython은 내장 자료형의 서브클래스에서 오버라이드한 메서드가 언제 호출되는지, 혹은 호출되지 않는지에 대해 명확한 규칙을 정의하지 않고, 일반적으로 서브클래스에서 오버라이드한 메서드 같은 객체의 다른 내장 메서드에 의해 결코 호출되지 않고, dict의 서브 클래스에서 오버라이드한 getitem()메서드는 내장된 get()과 같은 메서드에 의해 호출되지 않는다.

#__setitem__()을 오버라이드한 메서드를 무시하는 내장된 dict의 __init__()과 __update__() 메서드

class DoppelDict(dict):
	def __setitem__(self, key, value):
    	super().__setitem__(key, [value]*2)
        
dd = DoppelDict(one=1)
dd #{'one':1}
dd['two']=2
dd.update(three=3)
dd

내장 자료형은 '슈퍼클래스에서 구현된 메서드 안에서 호출하더라도 메서드 검색은 대상 객체의 클래스에서 시작해야 한다는 객체지향 프로그래밍의 기본 규칙을 어기고 있으나, missing()메서드는 예외적인 상황을 처리하는 메서드이므로 문서화된대로 작동한다.

허나, self.geT()이 self.getitem()을 호출하는 경우처럼 객체 안에서 호출할 때뿐만 아니라, 내장 메서드가 호출하는 다른 클래스의 오버라이드된 메서드에서도 발생한다.

#AnswerDict의 __getitem__()을 지나치는 dict.update()

class AnswerDict(dict):
	def __getitem__(self, key):
    	return 42
        
ad = AnswerDict(a='foo')
ad['a']
d={}
d.update(ad)
d['a']
d

profile
성장을 도울 아카이빙 블로그

0개의 댓글