流畅的Python-Python数据模型

Python模型其实就是对Python框架的描述,它规范了这门语言自身构建模型的接口,这些模块包括但不限于序列、迭代器、函数、类和上下文管理器

Python解释器碰到特殊的语法时,会使用特殊方法去激活一些基本的对象操作,这些特殊方法的名字以两个下划线开题,以两个下划线结尾(例如__getitem__)

比如obj[key]的背后就是__getitem__方法,为了求得my_collection[key]的值,解释器实际上会调用my_collection.__getitem__(key)方法。 len(obj)的背后就是__len__方法,为了求得my_collection的长度,解释器实际上会调用my_collection.__len__()方法。

这些特殊方法名能让对象的实现和支持以下的语法构架,并与之交互:

  • 迭代
  • 集合类
  • 属性访问
  • 运算符重载
  • 函数和方法调用
  • 对象的创建和销毁
  • 字符串表示形式和格式化
  • 管理上下文(即with块)

一摞Python风格的纸牌

示例: 展示如何实现__getitem__和__len__这两个特殊方法

import collections

Card = collections.namedtuple('Card', ['rank', 'suit'])


class FrenchDeck(object):
    # 牌面
    ranks = [str(n) for n in range(2,11)] + list('JQKA')
    # 花色
    suits = 'spades diamonds clubs hearts'.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, item):
        return self._cards[item]

说明: 使用collections.nametuple构建一个简单的类来表示一张纸牌,collections.nametuple()方法可以构建只有少数属性但没有方法的对象。

# Card类的使用
beer_card = Card('7', 'diamonds') print(beer_card)  

使用len()方法查看一叠牌有多少张

deck = FrenchDeck()
print(len(deck))

从一叠牌中抽取特定的一张牌, 比如说第一张和最后一张

# 抽取第一张牌
print(deck[0]) # 抽取最后一张牌
print(deck[-1])

因为__getitem__方法把[]操作交给了self._cards列表,所以deck类自动支持切片操作。

print(deck[0:3])

因为类实现了__getitem__方法,所以这一叠牌变成了可迭代对象,

# 正向迭代
for card in deck:
    print(card)

# 反向迭代
for card in reversed(deck):
    print(card)

如果一个类没有实现__contains__方法,那么in运算符就会按顺序做一次迭代搜索,所以,in运算符可以用在FrenchDeck类上。

print(Card('Q', 'hearts') in deck)  # True
print(Card('7', 'bearts') in deck)  # False

对纸牌类对象进行排序

suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)
print(suit_values)  # {'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)

说明: 排序主要是使用sorted内置方法,参数key接收排序的函数,suit_values表示花色的权重,排序的方法spades_high接收一张纸牌,然后通过获取纸牌的牌面和花色返回牌面的权值,

权值的计算公式为: 牌面 * 4 + 花色对应的value

猜你喜欢

转载自www.cnblogs.com/featherwit/p/12960862.html