파이썬스러운 객체

휴먼스케이프

안녕하세요. 휴먼스케이프의 개발자 bruno입니다.

이 번 포스트에서는 ‘루시아누 하말류’의 Fluent Python 9장 ‘파이썬스러운 객체’의 내용을 다루겠습니다.

이 장에선, ‘사용자 정의 클래스를, 어떻게 하면 파이썬스럽게 정의할 수 있는가?’에 대해서 설명합니다. 간단히 설명하면, 파이썬 내장함수에 사용할 수 있도록 ‘덕 타이핑’에 맞춰 클래스를 정의하는 것입니다.

만약 어떤 새가 오리처럼 걷고, 헤엄치고, 꽥꽥거리는 소리를 낸다면 나는 그 새를 오리라고 부를 것이다.

반복 가능한(iterable) 객체

__iter__() 를 구현하면 클래스의 인스턴스는 반복할 수 있게 됩니다. 제너레이터 표현식을 반환하면 됩니다.

객체 표현

repr()

객체를 개발자가 보고자 하는 형태로 표현한 문자열로 반환합니다.

__repr__() 에 구현

str()

객체를 사용자가 보고자 하는 형태로 표현한 문자열로 반환합니다.

__str__() 에 구현

bytes()

객체를 바이트 시퀀스로 표현합니다.

__bytes__() 에 구현

format()

‘포맷 명시자’에 따라 객체를 표현할 형식을 정해서 표현합니다.

__format__() 에 구현

대안 생성자

bytes()를 이용해서 인스턴스를 바이트 시퀀스로 표현했다. 그 반대도 가능합니다. 이 때 클래스에서 바로 인스턴스를 만들기 위해 classmethod 데커레이터를 사용합니다.

classmethod

인스턴스가 아닌 클래스에 연산을 수행하는 메서드를 정의합니다. 클래스 자체를 첫 번째 인수로 받습니다.

staticmethod

self(인스턴스)나 cls(클래스) 같은 첫 번째 인수가 없는 메서드를 정의합니다. 저자는 이런 용도라면 클래스 밖에 정의하라고 권유하고 있습니다.

인스턴스 해싱

해싱 가능하기 위해선 __hash__() 메서드를 구현해야 합니다. 해시 가능하면 set 또는 dict의 키로 사용할 수 있게 됩니다.

해시 가능하다:

수명 주기 동안 결코 변하지 않는 해시값을 갖고 있고(__hash__() 메서드가 필요하다), 다른 객체와 비교할 수 있으면(__eq__() 메서드가 필요하다), 객체를 해시 가능하다고 한다. 동일하다고 판단되는 객체는 반드시 해시값이 동일해야 한다.

때문에 객체를 불변형으로 만들어야 합니다.

__로 시작하는 멤버 변수는 비공개 속성이 됩니다. 그런 후에 property 데커레이터를 이용해서 getter 메서드를 만듭니다.

__hash__() 메서드는 int 형을 반환해야 한다

hash값을 생성할 때, XOR 을 사용하기를 권장합니다.

비공개 속성과 보호된 속성

__로 시작하고, 언더바가 없거나 하나로 끝나는 속성은 __dict__에 ‘_클래스명__변수명__’ 이렇게 저장됩니다. 예를 들어 Vector2d클래스 내부에 __x 속성이 있으면 __dict__ 안에 _Vector2d__x로 저장됩니다. 따라서 외부에서 접근 및 수정이 가능합니다.

방법이 조금 복잡할 뿐 java와 같은 다른 언어에서도 private 속성들을 외부에서 접근할 수 있습니다. 다만 파이썬은 그 방법이 조금 더 쉬운 편일 뿐입니다.

__slots__ 클래스 속성으로 공간 절약하기

__slots__ 속성은 파이썬 인터프리터가 객체 속성을 dict대신 튜플에 저장하게 만듭니다. 튜플은 dict보다 메모리를 적게 사용하므로 메모리를 절약하는 효과가 있습니다.

__slots__ 사용시 주의점

인터프리터는 상속된 __slots__ 속성을 무시하므로 각 클래스마다 __slots__ 속성을 다시 정의해야 합니다.

__slots__를 명시하는 경우, __dict__를 __slots__에 추가하지 않는 한 객체는 __slots__에 명시되지 않은 속성을 가질 수 없게 됩니다. 그러나 __dict__를 __slots__에 추가하면 메모리 절감 효과가 반감됩니다.

__weakref__를 __slots에 추가하지 않으면 개체가 약한 참조의 대상이 될 수 없습니다.

Vector2d 클래스 코드 전체

마지막 정리를 위해 예제로 사용한 Vector2d 클래스 정의 전체를 첨부합니다. 이는 Fluent Python Github 에서도 확인할 수 있습니다.

마무리

이 챕터에서 제시한 ‘파이썬스러운 객체’를 만드는 방법은, 파이썬 내부 함수의 기능을 사용할 수 있도록, 특별 메서드들을 적절히 구현하는 것입니다. 하지만, 저자는 필요하지 않은 기능까지 구현해야 하는 건 아니라고 후설하고 있습니다.

‘파이썬의 선’은 ‘단순함이 복잡함보다 낫다’는 것이다.

감사합니다.

이 포스트는 루시아누 하말류의 책 [Fluent Python]을 참고해서 작성했습니다.

Get to know us better! Join our official channels below.

Telegram(EN) : t.me/Humanscape KakaoTalk(KR) : open.kakao.com/o/gqbUQEM Website : humanscape.io Medium : medium.com/humanscape-ico Facebook : www.facebook.com/humanscape Twitter : twitter.com/Humanscape_io Reddit : https://www.reddit.com/r/Humanscape_official Bitcointalk announcement : https://bit.ly/2rVsP4T Email : support@humanscape.io

기업문화 엿볼 때, 더팀스

로그인

/