Python 数据模型
目录
1. 语言特性
- Python 最好的品质之一是一致性,体现在 Python 的数据模型上
2. 数据模型
定义:是对 Python 框架的描述
作用:规范了这门语言自身构建模块的接口(API)
包括:不限于序列、迭代器、函数、类和上下文管理器
-
数据模型接口:
- 实现: Python 解释器碰到特殊的句法时,会使用特殊方法去激活一些基本的对象操作
- 特殊方法:以两个下划线开头,以两个下划线结尾
-
通过特殊方法可以实现的语言框架:
- 迭代
- 集合类
- 属性访问
- 运算符重载
- 函数和方法的调用
- 对象的创建和销毁
- 字符串表示形式和格式化
- 管理上下文(即 with 块)
-
通过实现特殊方法来利用 Python 数据模型的好处:
- 作为你的类的用户,他们不必去记住标准操作的各式名称
- 可以更加方便地利用 Python的标准库 eg:random.choice
3. 使用特殊方法
特殊方法调用:
- 特殊方法的存在是为了被 Python 解释器调用的,不需要直接调用它们
- 最好的选择是通过内置的函数(例如 len、 iter、 str,等等)
eg:len(obj) 会自动调用 obj.__len__()方法 - Python 内置的类型, CPython可能直接从一个 C 结构体里读取数据
__repr__
作用:
- 方便程序员调试和记录日志
- 所返回的字符串应该准确、无歧义,并且尽可能表达出如何用代码创建出这个被打印的对象
调用:
- repr() 函数
- “%r” % obj
- format(’{name!r}’, obj)
- 交互式控制台和调试程序(debugger)用 repr 函数获取字符串表示形式
- 如果对象没有 __str__ 函数,解释器会用 __repr__ 作为替代
__str__
作用:
- 终端用户使用
调用:
- str()
__bool__
调用: bool()
python 真假判断:
- 为了判定值 x 真假, Python会调用 bool(x),这个函数只能返回 True 或者 False
- bool(x)默认调用 x.__bool__(),__bool__ 必须返回布尔型
- 如果不存在,bool(x) 尝试调用 x.__len__()返回 0则 bool 返回 False;否则返回 True
- 两个方法都不存在,默认情况下,自定义的类的实例总是返回True
特殊方法概览
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__ |
附注
len 为什么不是普通方法
- 对于内置类型,len() 直接从C 结构体里读取对象长度,完全不会调用任何方法
- len 之所以不是一个普通方法,是为了让 Python 自带的数据结构 可以走后门,其他内置函数也是同样道理
- 同时由于它是特殊方法,也可以把 len 用于自定义数据类型
- 这种处理方式在保持内置类型的效率和保证语言的一致性之间找到了一个平衡点
4. 常用模块
模块 | 作用 |
---|---|
collection.namedtuple() | 构建只有少数属性但是没有方法的对象,比如数据库条目 |
random.choice(seq) | 从一个序列中随机选出一个元素 |
sorted() | 内置排序函数 |
decimal.Decimal | 高精度浮点数 |
fractions.Fraction | 分数数值类型 |
延伸阅读
Python:
- Data Model:https://docs.python.org/3/reference/datamodel.html
- format: https://docs.python.org/2/library/string.html#formatstring-syntax
- __str__:http://stackoverflow.com/questions/1436703/difference-between-str-and-repr-in-python
书籍:
- 《 Python 技术手册(第 2 版)》- 对属性访问机制的描述
- 《 Python 参考手册(第 4 版)》
- 《 Python Cookbook(第 3版)中文版》
- 《The Art of the Metaobject Protocol》 - 元对象协议(metaobject protocol, MOP)
blog:
- Alex Martelli: http://stackoverflow.com/users/95810/alex-martelli
杂谈
元对象协议
- 元对象所指的是那些对建构语言本身来讲很重要的对象,
- 以此为前提, 协议也可以看作接口
- 也就是说,元对象协议是对象模型的同义词,它们的意思都是构建核心语言的 API
面向方面编程
- java: AspectJ
- pyhton: zope.interface http://docs.zope.org/zope.interface/
示例代码
|
|