最近在看《Fluent Python》一书,书中解释了Python很多重要的设计理念和实践,下面是我在看此书的读书笔记。Python的设计思想主要体现在它的数据模型上,而数据模型所描述和传递的API更能让你创造出和抽象出自己对象世界。数据模型是对Python框架的描述。 magic and dunder:magic是特殊方法的昵称,dunder是双下划线.
为了深入了解Python Data Model的内部实现,我们先看一下代码示例:
# -*- coding:utf-8 -*-
# -*- coding:utf-8 -*-
from collections import namedtuple
from random import choice
#namedtuple用于构建没有方法且少量属性的对象,比较方便的适用于数据库存储的实体对象。
Card = namedtuple('Card', 'rank suit')
class Deck(object):
'''自定义的对象,自己重写了__len__和__getitem__方法。'''
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = 'S D C H'.split()
def __init__(self):
self._cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks]
def __len__(self):
'''查看有多少张牌'''
return len(self._cards)
def __getitem__(self, pos):
'''为了实现deck[0],deck[2]模型,自动支持切片和可迭代对象'''
return self._cards[pos]
# 为了排序用的
suit_values = dict(S = 3, D = 1, C = 0, H = 2)
def sorted_high(card):
rank_value = Deck.ranks.index(card.rank)
return rank_value + len(suit_values) + suit_values[card.suit]
if __name__ == "__main__":
deck = Deck()
print(len(deck), deck[0])
a = choice(deck)
print(a)
#对于in操作,如果没有实现__contains__方法,in云算法会进行一次迭代搜索。
print(Card('A', 'H') in deck)
for i in sorted(deck, key= sorted_high):
print(i)
#输出为
52 Card(rank='2', suit='S')
Card(rank='4', suit='C')
True
Card(rank='2', suit='C')
.
.
.
Card(rank='A', suit='S')
Python的特殊方法主要为了供编译器使用和优化的,我们并不需要调用它,比如:我们调用len(deck),Python会自动调用object len()方法。如果我们所操作的对象是Python内置类型(List,str,bytearray等),len直接返回PyVarObject(表示内存长度可变的内置对象的结构体)里的db_size属性,不是方法,所以速度较快。通过内置的函数来使用特殊方法是最好的选择。 下面我们来看来实现一个向量运算的例子,比如:提供加减乘操作。
# -*- coding:utf-8 -*-
from math import hypot
class Vector(object):
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
def __repr__(self):
return 'Vector(%r,%r)' % (self.x, self.y)
def __abs__(self):
'''实现vector的长度计算'''
return hypot(self.x, self.y)
def __bool__(self):
'''默认情况下,自定义的类实例都是True,除非自己实现该函数。调用bool(x),x首先调用__bool__方法,如果不存在则去调用__len__方法。'''
return bool(abs(self))
def __add__(self, other):
'''实现vector1+vector2的加法操作'''
x = self.x + other.x
y = self.y + other.y
return Vector(x, y)
def __mul__(self, scalar):
'''实现vector1x10的加法操作'''
return Vector(self.x * scalar, self.y * scalar)
if __name__ == "__main__":
v1 = Vector(1, 2)
v2 = Vector(1, 2)
print(abs(v1))
print(v1 + v2)
print(v1 * 10)
#输出为
2.23606797749979
Vector(2,4)
Vector(10,20)
Python对象模型又称为Python数据模型
参考书籍 《Fluent Python》