刚开始看python,看到“魔法方法”这个词,我也是一脸懵逼,什么鬼?而且翻看官方文档,竟然连示例都没几个!
查阅资料才知道,其实就是一系列以双下划线开头”__”并以之结尾的方法。基本上python的面向对象能力就全靠它们了。
so,总结下一些常用的,作为自己以后复习查阅参考。
类的构造相关
__init__(self, [...)
类的构造器,类的构造器,当初始构造方法被执行(例如,我们执行 x = SomeClass(10,’foo’)),__init__
就会获得10和‘foo’作为参数。__init__
在python类的定义中经常被使用。
还有一个__new__
的方法,是比init方法更早调用的方法,一般不用,未详细了解。
然后是对应的有个__del__
方法,类似C++的析构函数,起到垃圾回收用处,但是python编辑器还在运行时,不能保证其一定执行,因此调用不稳定,很少用,也不推荐使用。
对象间的比较
__cmp__(self, other)
比较方法里面最基本的的魔法方法。实际上它实现了所有的比较运算符(如<, ==, !=)的行为,但也许不是你想要的行为(例如,一个实例是否和另一个实例相等应该由某个条件来决定,一个实例是否大于另一个实例应该由其他的条件来决定)。当self < other时该方法应该返回一个负整数,当self == other时返回0,self > other时返回正整数。通常来说最好是定义每个你需要的比较方法而不是一次性定义所有的比较方法,但是该方法是一个消除重复性的良途,并且当你有很多比较方法需要用相类似的条件去实现的时候这能让代码变得清晰。
__eq__(self, other)
定义相等符号的行为,==
__ne__(self,other)
定义不等符号的行为,!=
__lt__(self,other)
定义小于符号的行为,<
__gt__(self,other)
定义大于符号的行为,>
__le__(self,other)
定义小于等于符号的行为,<=
__ge__(self,other)
定义大于等于符号的行为,>=
数值处理魔术
单目运算操作与函数
__pos__(self)
实现一个取正数的操作(比如 +some_object ,python调用pos函数)
__neg__(self)
实现一个取负数的操作(比如 -some_object )
__abs__(self)
实现一个内建的abs()函数的行为
__invert__(self)
实现一个取反操作符(~操作符)的行为。想要了解这个操作的解释,参考the Wikipedia article on bitwise operations.
__round__(self, n)
实现一个内建的round()函数的行为。 n 是待取整的十进制数.
__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)
实现真实除法,注意,只有当你from future import division时才会有效
__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)
真除赋值,注意只有你 whenfrom future import divisionis,才有效.
__imod_(self, other)
模赋值,相当于 %= 运算符.
__ipow__
乘方赋值,相当于 **= 运算符.
__ilshift__(self, other)
左移赋值,相当于 <<= 运算符.
__irshift__(self, other)
左移赋值,相当于 >>= 运算符.
__iand__(self, other)
与赋值,相当于 &= 运算符.
__ior__(self, other)
或赋值,相当于 |= 运算符.
__ixor__(self, other)
异或运算符,相当于 ^= 运算符.
反射运算
__radd__(self, other)
反射加法
__rsub__(self, other)
反射减法的
__rmul__(self, other)
反射除法
__rfloordiv__(self, other)
反射地板除,使用//运算符的
__rdiv__(self, other)
反射除法,使用/运算符的.
__rtruediv__(self, other)
反射真除.注意只有from future import division 的时候它才有效
__rmod__(self, other)
反射取模运算,使用%运算符.
__rdivmod__(self, other)
长除法,使用divmod()内置函数,当divmod(other,self)时被调用.
__rpow__
反射乘方,使用**运算符的
__rlshift__(self, other)
反射左移,使用<<操作符.
__rrshift__(self, other)
反射右移,使用>>操作符.
__rand__(self, other)
反射位与,使用&操作符.
__ror__(self, other)
反射位或,使用|操作符.
__rxor__(self, other)
反射异或,使用 \^ 操作符.
类型转换魔法
__int__(self)
转换成整型.
__long__(self)
转换成长整型.
__float__(self)
转换成浮点型.
__complex__(self)
转换成 复数型.
__oct__(self)
转换成八进制.
__hex__(self)
转换成十六进制.
__index__(self)
当对象被切片时转换成int型。如果你定义了一个可能被用来做切片操作的数值型,你就应该定义__index__.
__trunc__(self)
当 math.trunc(self) 使用时被调用.__trunc__返回自身类型的整型截取 (通常是一个长整型).
__coerce__(self, other)
执行混合类型的运算,如果转换不能完成,应该返回None;否则,要返回一对两个元数的元组self和other, 被操作成同类型。
表示你的类
如果有一个字符串来表示一个类将会非常有用。在Python中,有很多方法可以实现类定义内置的一些函数的返回值。
__str__(self)
定义当 str() 被你的一个类的实例调用时所要产生的行为。
__repr__(self)
定义 当 repr() 被你的一个类的实例调用时所要产生的行为。 str() 和 repr() 的主要区别是其目标群体。 repr() 返回的是机器可读的输出,而 str() 返回的是人类可读的。
__unicode__(self)
定义当 unicode() 被你的一个类的实例调用时所要产生的行为。 unicode() 和 str() 很相似,但是返回的是unicode字符串。注意,如果对你的类调用 str() 然而你只定义了 __unicode__() ,那么其将不会工作。你应该定义 __str__() 来确保调用时能返回正确的值,并不是每个人都有心情去使用unicode。
__format__(self, formatstr)
定义当你的一个类的实例被用来用新式的格式化字符串方法进行格式化时所要产生的行为。例如, “Hello, {0:abc}!”.format(a) 将会导致调用 a.__format__(“abc”) 。这对定义你自己的数值或字符串类型是十分有意义的,你可能会给出一些特殊的格式化选项。
__hash__(self)
定义当 hash()被你的一个类的实例调用时所要产生的行为。它返回一个整数,用来在字典中进行快速比较。请注意,这通常也承担着实现__eq__。有下面这样的规则:a == b 暗示着 hash(a) == hash(b) 。
__nonzero__(self)
定义当 bool() 被你的一个类的实例调用时所要产生的行为。本方法应该返回True或者False,取决于你想让它返回的值。
__dir__(self)
定义当 dir() 被你的一个类的实例调用时所要产生的行为。该方法应该返回一个属性的列表给用户,一般而言,实现 __dir__ 是不必要的,但是,如果你重新定义了__getattr__或__getattribute__(你将在下一节中看到)或者其它的动态生成属性,那么它对你的类的交互使用是至关重要的。
__sizeof__(self)
定义当 sys.getsizeof() 被你的一个类的实例调用时所要产生的行为。该方法应该以字节为单位,返回你的对象的大小。这通常对于以C扩展的形式实现的Python类更加有意义,其有助于理解这些扩展。
可调用对象
在Python中,方法是最高级的对象。这意味着他们也可以被传递到方法中,就像其他对象一样。这是一个非常惊人的特性。
在Python中,一个特殊的魔法方法可以让类的实例的行为表现的像函数一样,你可以调用它们,将一个函数当做一个参数传到另外一个函数中等等。这是一个非常强大的特性,其让Python编程更加舒适甜美。
__call__(self, [args...])
允许一个类的实例像函数一样被调用。实质上说,这意味着 x() 与 x.__call__() 是相同的。注意 __call__ 的参数可变。这意味着你可以定义 __call__ 为其他你想要的函数,无论有多少个参数。
复制
这个其实类似于C++里的深拷贝和浅拷贝的概念。
__copy__(self)
定义了当对你的类的实例调用copy.copy()时所产生的行为。copy.copy()返回了你的对象的一个浅拷贝——这意味着,当实例本身是一个新实例时,它的所有数据都被引用了——例如,当一个对象本身被复制了,它的数据仍然是被引用的(因此,对于浅拷贝中数据的更改仍然可能导致数据在原始对象的中的改变)。
__deepcopy__(self, memodict={})
定义了当对你的类的实例调用copy.deepcopy()时所产生的行为。copy.deepcopy()返回了你的对象的一个深拷贝——对象和其数据都被拷贝了。memodict是对之前被拷贝的对象的一个缓存——这优化了拷贝过程并且阻止了对递归数据结构拷贝时的无限递归。当你想要进行对一个单独的属性进行深拷贝时,调用copy.deepcopy(),并以memodict为第一个参数。
一些魔法方法的调用时机
版权声明:
本文由greedcoder创作、发表并维护,
采用自由分享-保留署名-非商用-禁止演绎4.0(CC BY-NC-ND 4.0)国际许可协议进行许可.
版权有一点,侵权不一定究!
本文永久链接:https://greedcoder.github.io/2016/08/23/python-magic-methods/