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.网络通信概念 说 ...
随机推荐
- 解决VirtualBox 上的XP 关机时重启 , 启动时蓝屏 ,点击电源选项蓝屏
三个问题一次性解决. 启动时的蓝屏显示错误信息是: STOP 0x000000CE (...) DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATION ...
- EntityFramework - Code First - 数据迁移
需求 在更新模型之后同步更新数据库里的表,并不丢失原有数据 使用默认值填充新增加的字段 EntityFramework迁移命令 Enable-Migrations 启用迁移 Add-Migration ...
- 商业级别Fortify白盒神器介绍与使用分析
转自:http://www.freebuf.com/sectool/95683.html 什么是fortify它又能干些什么? 答:fottify全名叫:Fortify SCA ,是HP的产品 ,是一 ...
- Lua与C交换
1.C调用Lua函数 (1) 首先要进行Lua的初始化,这个主要是lua_open和luaL_openlibs函数 (2)然后是解析并编译lua的代码,这个主要是luaL_dofile函数 (3) ...
- leetcode - 3、Longest Substring Without Repeating Characters
题目链接:https://leetcode.com/problems/longest-substring-without-repeating-characters/description/ 题目要求: ...
- [SoapUI] 通过Groovy写文本文件
如果文件已经存在,先删除,然后向文件中追加失败信息 if(maxRecordFail>0){ def testResultFile = new File(projectDir+"\\T ...
- python 网络编程 TCP/IP socket UDP
TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...
- SQL日期跟时间值序列
与数据操作相关的场景要生成日期和时间序列,序列的范围是从输入值@start到@end,且具有一定的时间间隔.这样的场景包括填充数据仓库中的时间维度.应用程序的运行时间安排以及其他.可以借助http:/ ...
- [GO]并行和并发的区别
并行:指在同一时刻,有多条指令在多个处理器上同时执行 并发:指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只有把时 ...
- shell 编程 变量
转自:http://blog.csdn.net/qq504196282/article/details/52994249 shell之变量和引用 分类:SHELL编程基础 (470) (0) 举报 ...