"fluent python" 1장을 정리한 내용입니다.
"Pythonic" 한 코드를 작성하기 위한 필수적인 내용
Python 데이터 모델은 Python을 설명하는 프레임워크
Python내부의 sequences, functions, iterators, corotuines, classes, context managers 과 같은 Python 언어 자체의 구성단위들에 대한 인터페이스를 정의함
새로운 클래스를 작성하기위해 data model을 이용한다면, Python interpreter 가 special methods를 호출하여 기본적인 객체간 연산을 수행
example
collection[key] --> collection.__getitem__(key)
special methods는 아래와 같은 객체 기본연산을 지원
- collections
- attribute access
- iteration
- operator overloading
- function and method invocation
- string representation and formatting
- manage contexts using the with or async with statements
special methods 을 이용하는 장점
superclass에 special methods가 구현되어 있는 object를 상속할때, Python Data Model을 이용하여 기능과 구성을 이용
-> 이 경우, objects가 마치 Python sequence처럼 작동
special methods 는 Python interpreter가 호출하
special methods 를 직접 호출 하지 않음으로, 이용할때는 len() 과 같이 일반 메소드를 호출하는 것 처럼 이용
Python interpreter가 list, str, bytearray, numpyarray와 같이 built-in type을 다룰때 더 빠르게 작업을 수행
special methods는 암묵적으로 호출 ex) for loop
일반적으로 special methods를 직접 호출하는 일은 없으나, 예외적으로 사용자가 구현한 superclass 안에 __init__
메서드를 호출
sepcial method를 호출하는 것보다, 관련 built-in 함수를 이용해야함
(len, str, iter..)
__repr__
는 ‘출력될 수 있는 표현’(printable representation)을 문자열의 형태로 반환
ex ) < vector obeject 0x23423423>
반대로,__str__
은 str()에 의해 호출되며, 명시적으로 print function을 이용하기 때문에 객체의 이름이 아니라, 사용자가 이용하기 좋은 방식의 형태로 값반환
ex) vector( 2,3 )
Python interpreter는 __str__
을 호출하였다가 실패하면, __repr__
를 호출하기 때문에, 둘중에 하나만 구현하여야 한다면, __repr__
구현
__str__
vs __repr__
__str__
은 이용자에게 읽기 좋은 형태
__repr__
명확한 출력이며, 이용자는 거의 쓸일이 없다..!
자세한것은 링크에 설명이 잘 되어있다. -> 링크
Python 자체에도 bool type이 있지만, if나 while, and나 or에 대한 피연산자로서 bool형 연산이 필요하다면 지원
어떤 객체 x 가 참인지 거지인지를 판별하기 위해, Python은 bool(x)를 적용하며 리턴값은 Ture, False
기본적으로, __bool__
이나__len__
가 구현되어있지 않은 사용자 정의 객체 클래스는 참으로 간주
bool(x)은 호출 x.__bool__()
을 호출
__bool__
이 구현되어있지 않은경우, x.__len()__
을 호출
Python에서 collection API는 가장 중요
(출처 - fluent python chaper1. the Python Data Model )
iterable, sized, container, reversible, sequence, mapping, set 은 모두 추상메소드이며, list나 dic과 같은 하위클래스를 생성할때 상속받아 이용가능
-> special method로 이용 가능
모든 collection api 추상 메소는 하나의 special method로 대응
collection 추상 메소드는 다음과 같은 세가지를 반드시 구현
1. iterable to support for upacking and other forms of iteration
2. sized to support the len built-in function
3. container to support the in operator
파이썬은 collection 추상메소드를 상속하기위해 구체적인 클래스가 필요하지 않기때문에 __len__
을 구현하는 모든 클래스가 Sized
의 인터페이스를 이용가능
collection
의 중요한 3가지 특징Python 공식 문서 ( https://docs.python.org/3/reference/datamodel.html) 에서 약 80여가지 sepcial methods의 이름과 사용 방법을 확인 할 수 있으며, 산술, 비교, 비트연산자를 위해 사용가능
len(x)는 x가 내장형 타입의 객체일때 매우 빠르게 작동
-> CPython의 내장객체에서는 메서드를 구현하지 않고 구조체에서 바로 필드를 읽어오기 때문에 가능
기본형 객체에서 빠르고, 효율적으로 작동해야하는 연산에 대해서는 Python Data Model에서는 특별하게 취급하여 메서드라고 부르지 않음
__len__
을 이용하여 직접 정의도 가능
special methods를 구현함으로서, 사용자의 객체는 내장 타입처럼 작동하면서, Pythonic한 코딩을 이용할 수 있게된다.
debugging이나 logging, 최종사용자에게 보여주기 위한 형태로 이용 하기위해, Python객체는 반드시 사용가능한 문자타입의 rpresentation을 제공한다.
-> __repr__
와 __str__
이 data model 안에 존재하는 이유이다.
sequence 처럼 행동하기 위해 special method를 이용하는데, sequence 처럼 이용하면 다양하게 활용 가능하기 때문이다.
연산자 오버로딩을 이용해서 Python은 내장형에서 decimal.decimal부터 fractions.Fracrion까지 산술연산을 모두 지원한다.
Pyhthon documentation에서 부르는 Data Model은 사실은 Object Model과 같다고 보는 견해가 많다.
객체 모델이란 특정 컴퓨터 프로그래밍 언어에서의 일반적인 객체의 속성이라고 정의되고, 이는 Python Data Model에 대한 설명과 같기 때문