[流畅的python]-第一章-python数据模型笔记

Python数据模型

Python风格的设计思想,体现在python的数据模型上,数据模型其实是对python框架的描述,它规范了这门语言自身构建模块的接口,这些模块包括但不限于序列、迭代器、函数、类和上下文管理器。

1.1 一摞Python风格的纸牌

import collections      # collections.namedtuple用以构建只有少数属性但没有方法的对象
from random import choice

Card = collections.namedtuple('Card', ['rank', 'suit']) # 构建纸牌对象,分别有序列和花色两个属性

class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')  # 分别构建2-10和JQKA序列,用+进行链接 
    suits = 'spades diamonds clubs hearts'.split()  # 构建花色的list
    
    def __init__(self):  # 创建一副牌,按照花色顺序建立2-A
        self._cards = [Card(rank, suit) for suit in self.suits
                                        for rank in self.ranks]

    def __len__(self):  # len作为特殊函数,可以len(对象)使用,所以只有self;
        return len(self._cards)  # self._cards是list,可以直接使用len来读取长度
    
    def __getitem__(self, position):  # 返回postion索引对应数值
        return self._cards[position]

deck = FrenchDeck()

# __getitem__将[]的操作提交给self._cards列表,所以支持以下操作:随机抽取、索引、切片、迭代
choice(deck)
deck[:3]  # 提取前三张牌
deck[12::13]  # 从deck[12]开始,每13张牌取一张,即提取所有的A牌
for card in reversed(deck):  #doctest: +ELLIPSIS  此命令可用来避免省略号
    print(card)
Card('Q', 'hearts') in deck

# 给扑克牌排序,因为FrenchDeck中实现了__len__和__getitem__两个方法,所以如同python自有的数据类型
# 自然,可以使用标准库中的random.choice reversed sorted函数
suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)
def spades_high(card):
    rank_value = FrenchDeck.ranks.index(card.rank)
    return rank_value*len(suit_values) + suit_values[card.suit]
for card in sorted(deck, key=spades_high):
    print(card)

1.2 如何使用特殊方法

特殊方法的存在是为了被Python解释器调用,例如len(Deck),而不是Deck.__len__();
特殊方法的调用是隐式的;
不要随意添加特殊方法。

1.2.1模拟数值类型

from math import hypot
class Vector:

    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):
        return hypot(self.x, self.y)

    def __bool__(self):
        # return bool(abs(self))
        return bool(self.x or self.y)

    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)

1.2.2 字符串表示形式

st = "weihua"
print("%r" % st)
print("{!r}".format(st))

__repr____str__的区别在于:
__repr__的实现中,用到了%r来获取对象各个属性的标准字符串表示形式,在交互式控制台打印一个对象;使用Vector(3,4);后者在str()函数被使用,或者在print函数打印一个对象的时候才被调用,并且它返回的字符串对终端用户更友好。

1.2.3 算术运算符

通过定义方法:__add____mul__,实现类中+和*两个算术运算符

1.2.4 自定义的布尔值

bool(x)的背后是调用x.__bool__()的结果

你可能感兴趣的:(有用的python学习记录,python,开发语言,numpy)