python 魔术方法(四)非常用方法与运算符重载方法大合集

2019-04-07 21:41:02   最后更新: 2019-04-07 21:52:56   访问数量:153




前面三篇文章中,我们介绍了最为常用的一系列 python 的魔术方法

python 魔术方法(一) 自定义容器类与类属性控制

python 魔术方法(二) 对象的创建与单例模式的实现

python 魔术方法(三)对象的打印 -- __repr__ 与 __str__

 

还有一些并不是那么常用,但却会在你需要他们的关键时刻产生特别的效果的一系列魔术方法

本文就将带你一一领略他们的用法和用途

 

 

在 Python 中,方法是一种特殊的对象,他们除了可调用外,也和其他对象一样可以作为其他方法的参数

利用特殊的魔术方法 -- __call__ 我们可以让类实例也具有和普通方法一样的特性 -- 可调用

class TechlogTest: def __call__(self, *args, **kwargs): print('hello world') if __name__ == '__main__': test = TechlogTest() test()

 

 

打印出了:

hello world

 

此前的文章中,我们已经介绍过深拷贝与浅拷贝:

python 序列与深浅拷贝

 

浅拷贝 -- copy.copy

copy 包提供了浅拷贝和深拷贝的特性

浅拷贝是将原始对象的所有数据都拷贝一份,但是原始数据中的子对象却并不进行拷贝,只是拷贝子对象的引用

这样,虽然修改原始对象中任何普通元素都不会影响到拷贝出来的对象,但是对原始对象中子对象的修改就会同步到拷贝对象中

>>> import copy >>> alist = [1,2,3,["a","b"]] >>> c = copy.copy(alist) >>> c [1, 2, 3, ['a', 'b']] >>> alist[2] = 5 >>> alist [1, 2, 5, ['a', 'b']] >>> c [1, 2, 3, ['a', 'b']] >>> alist[3].append('c') >>> alist [1, 2, 5, ['a', 'b', 'c']] >>> c [1, 2, 3, ['a', 'b', 'c']]

 

 

深拷贝 -- copy.deepcopy

与浅拷贝不同,深拷贝会递归拷贝对象及其所有的子对象

>>> import copy >>> alist = [1,2,3,["a","b"]] >>> c = copy.deepcopy(alist) >>> alist[3].append("c") >>> c [1, 2, 3, ['a', 'b']] >>> alist [1, 2, 3, ['a', 'b', 'c']]

 

 

魔术方法 __copy__ 与 __deepcopy__

对于基础类型,copy.copy 与 copy.deepcopy 两个操作可以分别如预期的工作,但对于我们的自定义类型,Python 解释器就无能为力了,如果想让 copy.copy 与 copy.deepcopy 能够正常工作,我们就必须实现下面两个魔术方法

__copy__(self) __deepcopy__(self, memodict={})

 

 

Python 2.5 引入了 with 关键字,用来实现程序运行上下文的自动清理

with open("foo.txt") as fd: # do something use fd

 

上述代码在 with 块运行结束时会自动完成 fd 的 close 操作,那么,这是如何实现的呢

当 with 块被执行时,解释器会自动调用对象的 __enter__ 方法

而在 with 块结束时,解释器则会自动调用对象的 __exit__ 方法,__exit__ 方法最终可以选择返回 True 或抛出异常

 

Python 有两个内置函数用来判断一个类的类型或继承关系:isinstance 和 issubclass

虽然绝大部分情况下,我们只要按照默认的工作来使用他们即可,但某些特殊情况下,能够改变并指定他们的行为方式,将十分有用

__instancecheck__(self, instance) __subclasscheck__(self, subclass)

 

 

用于比较的魔术方法

__cmp__(self, other) -- 是比较方法里面最基本的的魔法方法

__eq__(self, other) -- 定义相等符号的行为,==

__ne__(self,other) -- 定义不等符号的行为,!=

__lt__(self,other) -- 定义小于符号的行为,<

__gt__(self,other) -- 定义大于符号的行为,>

__le__(self,other) -- 定义小于等于符号的行为,<=

__ge__(self,other) -- 定义大于等于符号的行为,>=

 

数值计算的魔术方法

单目运算符和函数

__pos__(self) -- 实现一个取正数的操作

__neg__(self) -- 实现一个取负数的操作

__abs__(self) -- 实现一个内建的abs()函数的行为

__invert__(self) -- 实现一个取反操作符(~操作符)的行为

__round__(self, n) -- 实现一个内建的round()函数的行为

__floor__(self) -- 实现math.floor()的函数行为

__ceil__(self) -- 实现math.ceil()的函数行为

__trunc__(self) -- 实现math.trunc()的函数行为

 

双目运算符或函数

__add__(self, other) -- 实现一个加法

__sub__(self, other) -- 实现一个减法

__mul__(self, other) -- 实现一个乘法

__floordiv__(self, other) -- 实现一个“//”操作符产生的整除操作()

__div__(self, other) -- 实现一个“/”操作符代表的除法操作

__truediv__(self, other) -- 实现真实除法

__mod__(self, other) -- 实现一个“%”操作符代表的取模操作

__divmod__(self, other) -- 实现一个内建函数divmod()

__pow__ -- 实现一个指数操作(“**”操作符)的行为

__lshift__(self, other) -- 实现一个位左移操作(<<)的功能

__rshift__(self, other) -- 实现一个位右移操作(>>)的功能

__and__(self, other) -- 实现一个按位进行与操作(&)的行为

__or__(self, other) -- 实现一个按位进行或操作的行为

__xor__(self, other) -- 实现异或操作

 

增量运算

__iadd__(self, other) -- 加法赋值

__isub__(self, other) -- 减法赋值

__imul__(self, other) -- 乘法赋值

__ifloordiv__(self, other) -- 整除赋值,地板除,相当于 //= 运算符

__idiv__(self, other) -- 除法赋值,相当于 /= 运算符

__itruediv__(self, other) -- 真除赋值

__imod_(self, other) -- 模赋值,相当于 %= 运算符

__ipow__ -- 乘方赋值,相当于 **= 运算符

__ilshift__(self, other) -- 左移赋值,相当于 <<= 运算符

__irshift__(self, other) -- 左移赋值,相当于 >>= 运算符

__iand__(self, other) -- 与赋值,相当于 &= 运算符

__ior__(self, other) -- 或赋值

__ixor__(self, other) -- 异或运算符,相当于 ^= 运算符

 

类型转换

__int__(self) -- 转换成整型

__long__(self) -- 转换成长整型

__float__(self) -- 转换成浮点型

__complex__(self) -- 转换成复数型

__oct__(self) -- 转换成八进制

__hex__(self) -- 转换成十六进制

__index__(self) -- 如果你定义了一个可能被用来做切片操作的数值型,你就应该定义 __index__

__trunc__(self) -- 当 math.trunc(self) 使用时被调用 __trunc__ 返回自身类型的整型截取

__coerce__(self, other) -- 执行混合类型的运算

 

欢迎关注微信公众号,以技术为主,涉及历史、人文等多领域的学习与感悟,每周三到七篇推文,全部原创,只有干货没有鸡汤

 

 

《流畅的 python》

https://www.cnblogs.com/pyxiaomangshe/p/7927540.html

 






python      面向对象      魔术方法      运算符重载     


京ICP备15018585号