此笔记用于记录《流畅的Python》一书的学习要点,与各位Python爱好者分享,以后每周至少更新两章内容,完全是基于该书的精华总结,并以此监督自己,让自己在学习python的道路一直前进!
Python数据模型:是对Python框架的描述,规范了这门语言自身构建模块的接口,这些模块包括但不限于序列、迭代器、函数、类和上下文管理器。(个人认为,python的数据模型其实就是构成我们程序猿使用的诸如序列、迭代器、函数、类等框架的底层实现,供框架本身调用。)
python中含有大量的特殊方法(__X__),这些特殊函数我们称之为魔术方法或者双下方法。在做基础对象操作的时候,解释器可能背后调用的可能就是一些特殊方法。比如:obj[key]调用__getitem__方法。my_collection[key]==my_collection.__getitem__(key)。
通过一个扑克牌的例子来看看python重载特殊函数的强大之处:
import collections
from randomimport choice
Card = collections.namedtuple('card', ['rank', 'suit']) #namedtuple用来创建只有少量属性,没有方法的对象
#扑克牌类,通过该类实例化的对象拥有其他一般类型一样的属性。
class FrenchDeck:
ranks = [str(n)for nin range(2, 11)] +list('JQKA')
suit ='spades diamonds clubs hearts'.split()
def __init__(self):
self._cards = [Card(rank, suit)for rankin self.ranksfor suitin self.suit] #_cards是一个list
def __len__(self):
return len(self._cards) 返回纸牌的总数
def __getitem__(self, item):
return self._cards[item] 返回某一张纸牌对象
>>>deck = FrenchDeck()
>>>len(deck) #返回52
>>>deck[0] #返回Card(rank='2', suit='spades')
通过特殊方法的例子,我们知道了重载的特殊函数之后的强大之处。总结一下,特殊方法怎么使用?首先,特殊方法是被python解释器调用的,我们一般不会显式调用,也就是一般不会my_obj.__len__(),而应该是len(my_obj),如果自己没有实现特殊函数,python回去调用默认的特殊函数。也就是说,特殊方法的调用是隐式的。
此外,利用特殊方法,可以让自定义的对象(比如类实例)通过加号"+"进行运算。下面我们定义一个二维向量,实现二维向量的运算符计算。
from mathimport hypot
class Vector():
def __init__(self, x=0, y=0):
self.x = x
self.y = y
#把对象以字符串的形式表达出来。__str__在str()被调用或者print()被调用的时候才被调用。如果没有实现__str__,但是实现了__repr__,那么,print()打印自定义对象时,调用__repr__。
def __repr__(self):
return 'Vector({!r}, {!r})'.format(self.x, self.y)
def __str__(self):
return 'vector({!r}, {!r})'.format(self.x, self.y)
#求直角三角形斜边长
def __abs__(self):
return hypot(self.x, self.y)
#判断向量是否为真
def __bool__(self):
return bool(abs(self))
#两个向量相加
def __add__(self, other):
x =self.x + other.x
y =self.y + other.y
return Vector(x, y)
#向量与某一值相乘
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
#向量的长度
def __len__(self):
return self.x +self.y
网友评论