在定制类的过程中,添加的方法和属性能完成大部分工作。但若想要类表现出一些特殊行为或者能够响应某些内建函数或操作符,那么就需要构建一些特殊方法。这些特殊方法的标识是方法名以双下划线(__)开头与结尾,除了常用的构造器 __init__() 外,还有一些常用的特殊方法。

基础方法: C.__new__(self[,arg1,…])        构造器(带一些可选的参数);通常用在设置不可变数据类型的子类

C.__del__(self)        解构器

C.__str__(self)        可打印的字符串输出;内建 str() 及 print() 函数

C.__repr__(self)        运行时的字符串输出;内建 repr() 函数及 ' ' 操作符

C.__call__(self,*args)        用于可调用的实例;可以用来替代闭包的实现

C.__nonezero__(self)        为实例定义 False 值;内建 bool() 函数

C.__len__(self)        长度;内建 len()

类的值比较: C.__cmp__(self,obj)        对象比较;内建 cmp()

C.__lt__(self,obj) & C.__le__(self,obj)        小于或小于等于;内建< & <=

C.__gt__(self,obj) & C.__ge__(self,obj)        大于或大于等于;内建 > & >=

C.__eq__(self,obj) & C.__ne__(self,obj)        等于或不等于;内建 = & !=

类的属性: C.__getattr__(self,attr)        获取属性;内建 getattr();仅在属性没有找到时调用

C.__setattr__(self,attr)        设置属性

C.__delattr__(self,attr)        删除属性

C.__getattribute__(self,attr)        获取属性;内建 getattr();总是被调用

C.__get__(self,attr)        (描述符)获取属性

C.__set__(self,attr)        (描述符)设置属性

C.__delete__(self,attr)        (描述符)删除属性

数值类型,二进制操作符: C.__*add__(self,obj)        加;+ 操作符

C.__*sub__(self,obj)        减;+ 操作符

C.__*mul__(self,obj)        乘;* 操作符

C.__*dev__(self,obj)        除;/ 操作符

C.__*truediv__(self,obj)        真正的除法;/ 操作符

C.__*floordiv__(self,obj)        地板除;// 操作符

C.__*mod__(self,obj)        取模;% 操作符

C.__*divmod__(self,obj)        除和取模;内建 divmod()

C.__*pow__(self,obj[,mod])        乘幂;内建 pow() ; ** 操作符

C.__*lshift__(self,obj)        左移位;<< 操作符

C.__*rshift__(self,obj)        右移位;>> 操作符

C.__*and__(self,obj)        按位与;& 操作符

C.__*or__(self,obj)        按位或;| 操作符

C.__*xor__(self,obj)        按位异或;^ 操作符

数值类型,一元操作符: C.__neg__(self)        一元负

C.__pos__(self)        一元正

C.__abs__(self)        绝对值;内建 abs()

C.__invert__(self)        按位求反;内建 ~ 操作符

数值类型,数值转换: C.__complex__(self, com)        内建 complex()

C.__int__(self)        内建 int()

C.__float__(self)        内建 float()

数值类型,数值压缩: C.__index__(self)        在有必要时,压缩可选的数值类型为整型(比如用于切片索引时等)

序列类型: C.__len__(self)        序列中的项目数

C.__getitem__(self, ind)        获取一个元素

C.__setitem__(self, ind,val)        设置一个元素

C.__delitem__(self, ind)        删除一个元素

C.__getslice__(self, ind1,ind2)        获取切片元素

C.__setslice__(self, i1, i2,val)        设置切片元素

C.__delslice__(self, ind1,ind2)        删除切片元素

C.__contains__(self, val)        含有成员;内建 in 关键字

C.__*add__(self,obj)        串联;+ 操作符

C.__*mul__(self,obj)        重复;* 操作符

C.__iter__(self)        生成迭代器;内建 iter() 函数

映射类型: C.__len__(self)        类中的项目数

C.__hash__(self)        散列(hash)函数值

C.__getitem__(self,key)        获取某个值

C.__setitem__(self,key,val)        设置某个值

C.__delitem__(self,key)        删除某个值

C.__missing__(self,key)        给定键若不存在,则返回一个默认值

一般常用的特殊方法就是上面这些,某些如 coerce() 这样在 Python3 中被删除或失效的内建函数就没有再列出来。因为 Python 的内建类型已经能够满足日常需求,所以下面的例子就只来实现一个功能吧:虽然 float 类型有 .hex() 方法,但内建的 hex() 函数却不支持 float 类型。所以我们来自定义一个可以被内建的 hex() 调用的浮点类型。为了省事,我们就直接从 float 派生了~

class iFloat(float):

def __index__(self):

return int(self)

运行结果如下:

>>> a = iFloat(1.1)

>>> hex(a)

'0x1'

P.S. 上面这个例子是个伪栗子。因为他实际是通过将浮点数强制转换为整数来满足调用 hex() 函数的条件的。按照官方文档的说法,hex() 函数只接受 int 类型做参数,你在 iFloat 里实现 __hex__() 也没用,这也是我把 __oct__() 和 __hex__() 从上面删除的原因。同时按照官方文档的说法,如果你硬要调用内建 hex() 函数,则必须实现 __index__() 方法来返回一个整数(是的,还是得要整数…)

即,下面这种方法是木有用的:

class iFloat(float):

def __hex__(self):

return self.hex()

仍然会报错,尽管 __hex__(self) 可以返回正常值:

>>> a = iFloat(1.1)

>>> hex(a)

Traceback (most recent call last):

File "", line 1, in

hex(a)

TypeError: 'iFloat' object cannot be interpreted as an integer

>>> a.__hex__()

'0x1.199999999999ap+0'

我觉得这可能是因为内建 hex() 函数已经不只是调用 __hex__() 这么简单了。

__getattr__()与授权:

在Python 2.2 以前,标准类型还不可以派生。为解决此问题而常被使用的手段是“包装”,这种方式的行为就和他的名字一样:

class WrappedList():

def __init__(self,obj):

self.__data = obj

但这还不够,我们要实现的主要目标是在需要的时候可以像子类一样自动访问被包装对象的属性或方法。而实现这一功能的关键便是 __getattr__() 特殊方法。这个方法的作用是:当试图访问一个实例的属性时,本地属性会首先被找到,如果本地没有就会去类属性和祖先类属性里找,如果那里也没有的话,就会调用实例的 __getattr__() 方法。因此这里就给我们提供了一个将属性访问重定向到被包装的类型(伪父类)的机会。其具体的实现方法便是,在 __getattr__() 中调用内建的 getattr() 函数:

class WrappedList():

def __init__(self,obj):

self.__data = obj

def __getattr__(self,attr):

return getattr(self.__data,attr)

def __str__(self):

self.__atime = time()

return str(self.__data)

__repr__ = __str__

运行结果:

>>> a = WrappedList([1,2,3])

>>> a

[1, 2, 3]

>>> a.append(4)

>>> a

[1, 2, 3, 4]

不过这里仍有一个缺陷便是,当你对包装对象进行特殊行为时,例如上面 WrappedList 的切片操作,就会遇到问题。因为这已经超出了访问属性的范畴。因此在标准类型已经可以派生的现在,就没必要再去包装他们了,至于其他用途么,也可以先尝试用装饰器去实现。

python 类特殊方法_Python 定制类的特殊方法与授权相关推荐

  1. python 类 对象 方法 应用_Python 定制类与其对象的创建和应用

    1.创建新类Athlete,创建两个唯一的对象实例sarah james,他们会继承Athlete类的特性 >>> class Athlete: def __init__(self, ...

  2. Python 中的特殊方法(定制类):__str__、__cmp__、__len__、数学运算、类型转换、@property运用、__slots__和__call__函数

    Python中的特殊方法 Python的特殊方法定义在 class中,不需要直接进行显示调用,Python的某些操作符或者函数会自动调用对应的特殊方法.这些方法如:__str__().__len__( ...

  3. python中定制类_python定制类__str__(实例详解)

    在接下来的文章中,让我们明白什么是python中的自定义类.学习什么是python的自定义类,python定制类可以扮演何种角色在python编程.当你看到像__xxx__ __slots__变量或函 ...

  4. python定制手机套餐_python 定制类

    看到类似__slots__这种形如__xxx__的变量或者函数名就要注意,这些在Python中是有特殊用途的. __slots__我们已经知道怎么用了,__len__()方法我们也知道是为了能让cla ...

  5. python wait之后怎么起起来_python wait方法_Python条件类| 带有示例的wait()方法

    python wait方法 Python Condition.wait()方法 (Python Condition.wait() Method) wait() is an inbuilt method ...

  6. python wait方法_Python条件类| 带有示例的wait()方法

    python wait方法 Python Condition.wait()方法 (Python Condition.wait() Method) wait() is an inbuilt method ...

  7. python新式类c3算法_Python新式类的方法解析顺序MRO与Super

    新式类与经典类的方法解析顺序 MOR(方法解析顺序) 经典类:深度优先 DFS python3以前 新式类:广度优先 python2.2 新式类:广度优先的C3算法实现(拓扑排序) BFS pytho ...

  8. python 计时方法_Python计时器类| cancel()方法与示例

    python 计时方法 Python Timer.cancel()方法 (Python Timer.cancel() Method) cancel() is an inbuilt method of ...

  9. python新式类c3算法_Python 新式类继承关系的 C3 算法(Python 2.3 的方法解析顺序,MRO)...

    Python 新式类继承关系的 C3 算法(Python 2.3 的方法解析顺序,MRO) 翻译:刘硕 摘要:本文档面向于想要了解Python 2.3版本中 C3 方法解析顺序的 Python程序开发 ...

最新文章

  1. linux mysql 5.7 双机热备_2017年5月5日 星红桉liunx动手实践mysql 主主双机热备
  2. 给定两个整数m和n,求出m~n这段连续的整数中所有偶数的平方和以及所有奇数的立方和。
  3. javascript 西瓜一期 15 数据的存储单位
  4. CSS3实现光束和波浪
  5. mysql function
  6. vue - process.env 定义
  7. 构建自己的PHP框架(MVC)
  8. 拼装html字符串的最快方法
  9. 整理下常用到的css属性
  10. 友声电子秤设置软件_友声电子秤说明书精编版
  11. 【转】opencv中widthStep不一定等于width*nChannels的原因
  12. 从分类到选型,一文了解 SITOP 电源
  13. Unity SpriteAtlas实战使用
  14. 用python写一个NC(八)
  15. Cygwin环境使用第三方ARMGCC编译eCos系统
  16. 用Fiddler、Charles和mitmproxy进行手机抓包的配置教程
  17. zero eclipse_全球首款真无孔机!魅族zero亮相:支持屏幕发声和18W无线快充
  18. swing入门教程(五) Swing概念
  19. 如何自己租GPU服务器(阿里云)跑pytorch代码
  20. SpringBoot 必知必会的19个常用注解

热门文章

  1. SpringBoot和RabbitMQ集成
  2. 设计模式笔记一:工厂模式
  3. 韩顺平php视频笔记44 php小练习表单提交
  4. PyQt5学习笔记(二) 文本控件及使用
  5. minianaconda安装图形化界面
  6. H5实现拍照及相册图片上传
  7. 小程序点击显示隐藏(点击标题,内容显示,再次点击隐藏,同时切换箭头的状态,且默认第一组的内容显示)
  8. java冒泡排序法对数组进行排序
  9. 无法安装 计算机缺失,还原安装程序Windows缺失的文件 - Windows Client | Microsoft Docs...
  10. 多个vue项目合并成一个_再见Vlookup,合并多个表格发现一个最简单方法