首页 > 编程语言 > 详细

《流畅的Python》 Sequence Hacking, Hashing and Slicing(没完成)

时间:2019-12-16 21:50:44      阅读:85      评论:0      收藏:0      [点我收藏+]

序列修改,散列和切片

  •  基本序列协议:Basic sequence protocol: __len__ and __getitem__

 

本章通过代码讨论一个概念: 把protocol当成一个正式接口。协议概念和鸭子类型的关系。当创建自定义类型时,它的实际影响。


 

 

Vector类,一个自定义的序列类型

我们的实现Vector的策略是使用composition(组合),而不是继承。


 

10.3 序列和鸭子类型

协议是非正式的接口,只在文档内定义,在代码中不定义。

例如,序列协议在Python只需要__len__, __getitem__方法。任何类只要实现了这2个方法,它的实例就能当序列用。

import collections
Card = collections.namedtuple(Card, [rank, suit])
class FrenchDeck:
    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, position):
        return self._cards[position]
>>> import linshi
>>> d = linshi.FrenchDeck()
>>> d
<linshi.FrenchDeck object at 0x1041796d0>
>>> len(d)
52
>>> d[0]
Card(rank=2, suit=spades)

因为在FrenchDeck类中定义了序列协议的2个方法。所以它的实例就能使用序列类型的2个方法。

即使FrenchDeck类是Object的子类,但因为实现了序列协议,就可以把它当成一个序列类型。

这就是鸭子类型。拥有鸭子的行为,那么就把它当成鸭子。

 

protocols是非正式的非强制的,所以可以只实现一个协议的部分。

 

可切片的序列

__getitem__实现了切片功能:

>>> d[0:2]
[Card(rank=2, suit=spades), Card(rank=3, suit=spades)]

但是,返回的是一个list,而不是FrenchDeck实例。因此就不能使用FrenchDeck的其他实例方法。

 

那些内置序列类型,切片后返回的都是一个新的原本类型的实例,而不是其他类型。所以需要优化__getitem__方法中的代码。

《流畅的Python》 Sequence Hacking, Hashing and Slicing(没完成)

原文:https://www.cnblogs.com/chentianwei/p/12051345.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!