python高级(一)—— python数据模型(特殊方法)
本文主要内容
collections.namedtuple
__getitem__ 和 __len__
__repr__和__str__
__abs__、__add__和__mul__
__bool__
文中代码均放在github上:https://github.com/ampeeg/cnblogs/tree/master/python高级
本文内容的表格式总结
| 语 法 | 调用的方法(按照顺序寻找) | 备注 |
| list[2] | __getitem__(2) | |
| list[1:3:2] | __getitem__(slice(1,3,2)) | 切片时传入的参数是slice类型 |
| for i in object: | __iter__()、__getitem__() | __iter__需要返回迭代器,并不断调用next() |
| in object | __contains__()、__iter__()、__getitem__() | __iter__()、__getitem__()会按照顺序搜索 |
| print(object) | __str__()、__repr__() | |
| if object: | __bool__()、__len__() |
使用if、while等判断句时,会调用__bool__() 如果没有这两个方法,一般情况下,自定义的类总认为是真的 |
何为python的数据模型
本文所指的python数据模型,也可成为python中内置的对象模型(一切皆为对象),其包含的一些方法为特殊方法,在java中也称“魔术方法”。由于python文档里面喜欢使用“数据模型”这个词,所以本文依此称数据模型。
简单来说,数据模型就是python自有的数据类型,及其包含的特殊方法。例如:使用len()时会调用__len__特殊方法;使用list[]时会调用__getitem__方法;使用各类运算符也会调用其相对应的方法。从根本上而言,list[]、+、-、*、/、for i in x这些写法只是为了更简洁和更具有可读性,但内部跟其他操作一下,也是通过方法实现的,这就是特殊方法。
可命名元组(namedtuple)
# 导入可命名元组 |
__getitem__ 和 __len__
1、__len__
class Foo: |
2、__getitem__
from collections import namedtuple
Stock = namedtuple("stock", ["name", "price"])
class Foo:
|
重写__getitem__后就可直接遍历对象:
if __name__ == "__main__": |
3、继续说说for i in x: 语句
刚刚我们使用for i in foo时发现可以正常迭代,如果在Foo类中重写__iter__方法,则无法正确迭代了:
from collections import namedtuple
Stock = namedtuple("stock", ["name", "price"])
class Foo:
|
如果我们把以上__iter__方法改成如下,那么又可使用for语句了:
def __iter__(self):
return iter(self._stock)
事实上我们在使用for i in foo语句时,会先调用__iter__方法,返回一个迭代器,然后for循环会不断使用next()进行遍历;如果foo里面没有该方法,则会调用__getitem__,并会从0开始依次读取相应的下标,直到发生IndexError为止,这是一种旧的迭代协议。
同样的,使用in判断时,解释器会依次寻找__contains__、__iter__、__getitem__方法。
from collections import namedtuple
Stock = namedtuple("stock", ["name", "price"])
class Foo:
|
__repr__和__str__
# 接下来的例子引用自《流畅的python》 |
__abs__、__add__和__mul__
# 接上面的二维向量的例子
from math import hypot
class Vector:
def __init__(self, x=0, y=0):
|
__bool__
# 继续在上面列子中添加__bool__
from math import hypot
class Vector:
def __init__(self, x=0, y=0):
|
python中的全部特殊方法
本部分内容可以参考官方网站 https://docs.python.org/3/reference/datamodel.html#special-method-names
python中一共有83个特殊方法,其中47个用于算术运算、位运算和比较操作。我根据《流畅的python》中的整理,摘录如下两个表格
表1:跟运算符无关的特殊方法
| 类 别 | 方法名 |
| 字符串/字节序列表示形式 | __repr__、__str__、__format__、__bytes__ |
| 数值转换 | __abs__、__bool__、__complex__、__int__、__float__、__hash__、__index__ |
| 集合模拟 | __len__、__getitem__、__setitem__、__delitem__、__contains__ |
| 迭代枚举 | __iter__、__reversed__、__next__ |
| 可调用模拟 | __call__ |
| 上下文管理 | __enter__、__exit__ |
| 实例创建和销毁 | __new__、__init__、__del__ |
| 属性管理 | __getattr__、__getattribute__、__setattr__、__delattr__、__dir__ |
| 属性描述符 | __get__、__set__、__delete__ |
| 跟类相关的服务 | __prepare__、__instancecheck__、__subclasscheck__ |
表2:跟运算符相关的特殊方法
| 类 别 | 方法名和对应的运算符 |
| 一元运算符 | __neg__ -、__pos__ +、__abs__ abs() |
| 众多比较运算符 | __lt__ <、__le__ <=、__eq__ ==、__ne__ !=、__gt__ >、__ge__>= |
| 算数运算符 |
__add__ +、__sub__ -、__mul__ *、__truediv__ /、__floordiv__ //、 __mod__ %、__divmod__ divmod()、__pow__ **或pow()、__round__ round() |
| 反向算数运算符 | __radd__、__rsub__、__rmul__、__rtruediv__、__rfloordiv__、__rmod__、__rdivmod__、__rpow__ |
| 增量赋值算术运算符 | __iadd__、__isub__、__imul__、__itruediv__、__ifloordiv__、__imod__、__ipow__ |
| 位运算符 | __invert__ ~、__lshift__ <<、__rshift__ >>、__and__ &、__or__ |、__xor__ ^ |
| 反向位运算符 | __rlshift__、__rrshift__、__rand__、__rxor__、__ror__ |
| 增量赋值位运算符 | __ilshift__、__irshift__、__iand__、__ixor__、__ior__ |
如何使用特殊方法:
1、特殊方法的调用是隐式的,通常你的代码无需直接使用特殊方法。除非有大量的元编程存在,直接调用特殊方法的频率应该远远低于你去实现它们的次数。唯一的例外可能是__init__方法,你的代码里可能经常会用到它,目的是在你的子类的__init__方法中调用超类的构造器。
2、通过内置的函数(例如len、iter、str等)来使用特殊方法是最好的选择。这些内置函数不仅会调用特殊方法,通常还提供额外的好处,而且对于内置的类来说,它们的速度更快。
3、不要自己想当然地随意添加特殊方法,比如__foo__之类的,因为虽然现在这个名字没有被python内部使用,以后就不一定了。
——《流畅的Python》
python高级系列文章目录
python高级(一)—— python数据模型(特殊方法)的更多相关文章
- Python高级编程-Python一切皆对象
Python高级编程-Python一切皆对象 Python3高级核心技术97讲 笔记 1. Python一切皆对象 1.1 函数和类也是对象,属于Python的一等公民 ""&qu ...
- 第九章:Python高级编程-Python socket编程
第九章:Python高级编程-Python socket编程 Python3高级核心技术97讲 笔记 9.1 弄懂HTTP.Socket.TCP这几个概念 Socket为我们封装好了协议 9.2 cl ...
- 为什么用Python,高级的Python是一种高级编程语言
Python特性 如果有人问我Python最大的特点是什么,我会毫不犹豫地告诉他:它简单易学,功能强大.作为一个纯自由软件,Python有许多优点: 很简单.基于"优雅".&quo ...
- Python高级编程技巧(转)
译文:http://blog.jobbole.com/61171/ 本文展示一些高级的Python设计结构和它们的使用方法.在日常工作中,你可以根据需要选择合适的数据结构,例如对快速查找性的要求.对数 ...
- python高级——目录
目 录 python高级(一)—— python数据模型(特殊方法) python高级(二)—— python内置序列类型 python高级(三)—— 字典和集合(泛映射类型) python高级(四 ...
- python 高级之面向对象初级
python 高级之面向对象初级 本节内容 类的创建 类的构造方法 面向对象之封装 面向对象之继承 面向对象之多态 面向对象之成员 property 1.类的创建 面向对象:对函数进行分类和封装,让开 ...
- python高级之生成器&迭代器
python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container):多个元素组织在一起的数据结构 可迭代对象( ...
- python高级之面向对象高级
python高级之面向对象高级 本节内容 成员修饰符 特殊成员 类与对象 异常处理 反射/自省 单例模式 1.成员修饰符 python的类中只有私有成员和公有成员两种,不像c++中的类有公有成员(pu ...
- python高级之网络编程
python高级之网络编程 本节内容 网络通信概念 socket编程 socket模块一些方法 聊天socket实现 远程执行命令及上传文件 socketserver及其源码分析 1.网络通信概念 说 ...
随机推荐
- Java程序员常用工具类库 - 目录
有人说当你开始学习Java的时候,你就走上了一条不归路,在Java世界里,包罗万象,从J2SE,J2ME,J2EE三大平台,到J2EE中的13中核心技术,再到Java世界中万紫千红的Framework ...
- g2o 图优化
http://www.cnblogs.com/gaoxiang12/p/5244828.html 扩展里面csparse
- mosquitto ---配置SSL/TLS linux
mosquitto ---配置SSL/TLS 摘自: https://www.cnblogs.com/saryli/p/9821343.html 在服务器电脑上面创建myCA文件夹, 如在/home/ ...
- ASP.NET MVC 跨controller函数调用
var controller = DependencyResolver.Current.GetService<ControllerClassName>(); controller.User ...
- j中的substr(start,length)和substring(start,stop)
j中的substr(start,length)和substring(start,end) substring 1 substring 方法用于提取字符串中介于两个指定下标之间的字符(包头不包尾) 2 ...
- UDP问题
这两天使用C#的UdpClient,本机的服务是采用MFC的socket发的,用C#做客户端,然后客户端启动时,出现该条错误信息 ==通常每个套接字地址(协议/网络地址/端口)只允许使用一次. 笔记的 ...
- iBeacon的第一篇(基于Swift实现)
低功耗蓝牙技术现在几乎是只能手机的标配.随着这一技术的发展,苹果在2013年WWDC大会上,苹果推出iBeacon技术.该技术允许开发人员开发能够使用iBeacon硬件传感器的iOS应用程序,来为相应 ...
- Animation(动画效果)
Ctrl+6打开Animation窗口.选择物体,点击录制,保存录制文件后即为给该物体添加了动画效果. Animation可以修改某时间点的物体位置.大小.材质球上的所有属性.碰撞器等等. 可以通过修 ...
- post上传文件限制--另一种解决途径
问题:项目之前的上传功能是没有问题的,但是今天同样的代码上传一个压缩包的时候出现了问题,报的是struts.xml的错,说是找不到返回的映射, 问题截图: 很奇怪的问题,之前都没问题的,仔细对比后发现 ...
- Linux下安装python,ftp,Ubuntu和centos配置静态ip以及下载地址
一个服务器最多创建65535个端口Ubuntu apt-get aliyun转换https://www.cnblogs.com/hcl1991/p/7894958.htmlOpenSSLhttps:/ ...