01-data-model/frenchdeck.py
1. Python解释器碰到特殊的句法时,会使用__特殊方法__去激活一些基本的对象操作。
特殊方法的存在是为了被解释器用的。没有my_object.len()这种写法,应该用len(my_object)。
比如my_collection[key] -> my_coolection._getitem_(key)。
例如在class FrenchDeck中实现__len()__就可以使用len(object)。
实现 _getitem()_ 就可以使用deck[position]。
2. 很多时候__特殊方法__的调用是隐式的
比如for i in x: -> x._iter_(), 前提是__iter__在x中被实现。
3. Python内置了一个从序列中__随机选出__一个元素的函数random.choice。
from random import choice
a = [1,2,3,4,5]
choice(a)
4. 因为class FrenchDeck是__可迭代的__,所以__in运算符__可以用在FrenchDeck类上。另外,一个集合类型没有实现__contains__方法,那么in运算符会按顺序做一次迭代搜索。
>>> Card(‘Q‘, ‘hearts‘) in deck
True
>>> Card(‘Q‘, ‘beasts‘) in deck
False
01-data-model/vector2d.py
5. 用特殊方法__abs__实现向量求模,__add__实现‘+‘运算符,__mul__实现‘*‘运算符
6. 实现__repr__后
v1 = vector()
print(v1) 和 repr(v1) 都能把一个对象用字符串的形式表达出来。
7. %s与%r的不同, %r输出的是原始数据(raw data)
%s 用str()。 %r使用repr()。
%s 给用户看, %r供debug用。
__repr__ goal is to be unambiguous
__str__ goal is to be readable
如果一个对象没有__str__函数,Python解释器会用__repr__作为替代。
from datetime import datetime
d = datetime.today()
print(‘%s‘ % d)
print(‘%r‘ % d)
8. bool(x) 即 x._bool(),若不存在_bool() 则调用__len__()
9. 特殊方法一览 中文电子书P57
总结:
学术化:Python中偏爱说数据类型,其实意思是对象模型。通过实现Python数据类型的特殊方法,以提供丰富的元对象协议(元对象是对于构建语言来说核心的对象,协议意思是构建核心语言的API),自定义类型可以表现得和内置内容一样,从而写出更flexible和Pythonic的代码。
通俗化:通过实现特殊方法(_method_),可以赋予对象的某些行为、功能。