Fluent Python: Slice
Pyhton中序列类型支持切片功能,比如list:
>>> numbers = [1, 2, 3, 4, 5]
>>> numbers[1:3]
[2, 3]
tuple也是序列类型,同样支持切片。
(一)我们是否可以使自定义类型支持切片呢?
在Python中创建功能完善的序列类型不需要使用继承,只要实现符合序列协议的方法就可以,Python的序列协议需要__len__, __getitem__两个方法,比如如下的Vector类:
from array import array class Vector:
type_code = 'd' def __init__(self, compoments):
self.__components = array(self.type_code, compoments) def __len__(self):
return len(self.__components) def __getitem__(self, index):
return self.__components[index]
我们在控制台查看下切片功能:
>>> v1 = Vector([1, 2, 3])
>>> v1[1]
2.0
>>> v1[1:2]
array('d', [2.0])
在这里我们将序列协议委托给self.__compoments(array的实例),只需要实现__len__和__getitem__,就可以支持切片功能了。
(二)那么Python的切片工作原理又是怎样的呢?
我们通过一个简单的例子来查看slice的行为:
class MySequence:
def __getitem__(self, index):
return index
>>> s1 = MySequence()
>>> s1[1]
1
>>> s1[1:4]
slice(1, 4, None)
>>> s1[1:4:2]
slice(1, 4, 2)
>>> s1[1:4:2, 7:9]
(slice(1, 4, 2), slice(7, 9, None))
我们看到:
(1)输入整数时,__getitem__返回的是整数
(2)输入1:4表示法时,返回的slice(1, 4, None)
(3)输入1:4:2表示法,返回slice(1, 4, 2)
(4)[]中有逗号,__getitem__收到的是元组
现在我们来仔细看看slice本身:
>>> slice
<class 'slice'>
>>> dir(slice)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge
__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__',
'__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr_
_', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'indices', 'star
t', 'step', 'stop']
我们看到了熟悉的start, stop, step属性,还有一个不熟悉的indices,用help查看下(Pyhon的控制台是很有价值的工具,我们常常使用dir,help命令获得帮助):
Help on method_descriptor: indices(...)
S.indices(len) -> (start, stop, stride) Assuming a sequence of length len, calculate the start and stop
indices, and the stride length of the extended slice described by
S. Out of bounds indices are clipped in a manner consistent with the
handling of normal slices.
这里的indices能用于优雅的处理缺失索引和负数索引,以及长度超过目标序列长度的切片,这个方法会整顿输入的slice元组,把start, stop, step都变成非负数,且落在指定长度序列的边界内:
比如:
>>> slice(None, 10, 2).indices(5) # 目标序列长度为5,自动将stop整顿为5
(0, 5, 2)
>>> slice(-1, None, None).indices(5) # 将start = -1, stop = None , step = None 整顿为(4, 5, 1)
(4, 5, 1)
如果没有底层序列作为代理,使用这个方法能节省大量时间
上面了解了slice的工作原理,我们使用它重新实现Vector类的__getitem__方法:
from array import array
from numbers import Integral class Vector:
type_code = 'd' def __init__(self, compoments):
self.__components = array(self.type_code, compoments) def __len__(self):
return len(self.__components) def __getitem__(self, index):
cls = type(self)
if isinstance(slice, index):
return cls(self.__components[index]) # 使用cls的构造方法返回Vector的实例
elif isinstance(Integral, index):
return self.__components[index]
else:
raise TypeError("{} indices must be integers or slices".format(cls))
Fluent Python: Slice的更多相关文章
- 学习笔记之Fluent Python
Fluent Python by Luciano Ramalho https://learning.oreilly.com/library/view/fluent-python/97814919462 ...
- 「Fluent Python」今年最佳技术书籍
Fluent Python 读书手记 Python数据模型:特殊方法用来给整个语言模型特殊使用,一致性体现.如:__len__, __getitem__ AOP: zope.inteface 列表推导 ...
- Python slice() 函数
Python slice() 函数 Python 内置函数 描述 slice() 函数实现切片对象,主要用在切片操作函数里的参数传递. 语法 slice 语法: class slice(stop) ...
- Fluent Python: memoryview
关于Python的memoryview内置类,搜索国内网站相关博客后发现对其解释都很简单, 我觉得学习一个新的知识点一般都要弄清楚两点: 1, 什么时候使用?(也就是能解决什么问题) 2,如何使用? ...
- Python深入学习之《Fluent Python》 Part 1
Python深入学习之<Fluent Python> Part 1 从上个周末开始看这本<流畅的蟒蛇>,技术是慢慢积累的,Python也是慢慢才能写得优雅(pythonic)的 ...
- Fluent Python: Classmethod vs Staticmethod
Fluent Python一书9.4节比较了 Classmethod 和 Staticmethod 两个装饰器的区别: 给出的结论是一个非常有用(Classmethod), 一个不太有用(Static ...
- Fluent Python: @property
Fluent Python 9.6节讲到hashable Class, 为了使Vector2d类可散列,有以下条件: (1)实现__hash__方法 (2)实现__eq__方法 (3)让Vector2 ...
- Fluent Python: Mutable Types as Parameter Defaults: Bad Idea
在Fluent Python一书第八章有一个示例,未看书以先很难理解这个示例运行的结果,我们先看结果,然后再分析问题原因: 定义了如下Bus类: class Bus: def __init__(sel ...
- 《Fluent Python》---一个关于memoryview例子的理解过程
近日,在阅读<Fluent Python>的第2.9.2节时,有一个关于内存视图的例子,当时看的一知半解,后来查了一些资料,现在总结一下,以备后续查询: 示例复述 添加了一些额外的代码,便 ...
随机推荐
- 查询优化百万条数据量的MySQL表
转自https://www.cnblogs.com/llzhang123/p/9239682.html 1.两种查询引擎查询速度(myIsam 引擎 ) InnoDB 中不保存表的具体行数,也就是说, ...
- OpenStack(queens)最小化搭建记录——控制与计算共两个节点
境: 2台安装了centos7-minimal的主机 ip地址: 10.132.226.103/24 (controller) 10.132.226.104/24 (compute1) 1.配置主机名 ...
- Delphi XE5的Android开发平台搭建
Delphi XE5支持Android ARM的开发,可以在Android虚拟机里运行,因此建议将XE5安装在64bit的Windows,内存可以大于3GB Delphi XE5安装光盘中包含了最基本 ...
- 以某课网日志分析为例 进入大数据 Spark SQL 的世界
第1章 初探大数据 本章将介绍为什么要学习大数据.如何学好大数据.如何快速转型大数据岗位.本项目实战课程的内容安排.本项目实战课程的前置内容介绍.开发环境介绍.同时为大家介绍项目中涉及的Hadoop. ...
- C语言简易三子棋
这是本人依据现学知识写的简易三子棋,也不是那么简洁明了,望大佬指点 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include&l ...
- 前端框架---jQuery---一分钟下载使用
这里通过自己手动的方式“做”一个jQuery来使用,需要5步 1. 访问 https://jquery.com 2. 点击download 3. 拉到最下方,点击 JQuery CDN 4. 得到所有 ...
- 学习Emmet
学习Emmet 在进行Web开发时,就免不了需要编写html文件,如何快速(偷懒^-^)的进行编写html,是个大问题,上网找了一下,发现了一个好东西 ,视频教程可以看下小马技术Emmet爆速开发, ...
- Titanic幸存预测分析(Kaggle)
分享一篇kaggle入门级案例,泰坦尼克号幸存遇难分析. 参考文章: 技术世界,原文链接 http://www.jasongj.com/ml/classification/ 案例分析内容: 通过训练集 ...
- SDR软件无线电知识要点(三)EVM
SDR软件无线电知识要点(三)EVM 信号质量如何评估 Noise Figure (NF) or sensitivity and Error Vector Magnitude (EVM) provid ...
- leetcode-746-Min Cost Climbing Stairs(动态规划)
题目描述: On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once yo ...