python运算符重载

时间:2021-10-28 00:06:19
1、打印操作会首先尝试__str__和str内置函数,他通常返回一个用户友好显示。__repr__用于所有其他环境,用于交互式模式下提示回应以及repr函数,如果没有使用__str__,则会使用print和str。它通常返回一个编码字符串,可以用来重新创建对象,或则给开发者一个详细的显示。总而言之,除了当定义一个__str__的时候,使用print和str。然而需要注意,如果没有定义__str__,打印还是使用__repr__,反过来不成立。在交互模式下,只适用__repr__,并且根本不尝试__str__.

2、__str__,__repr__都必须返回字符串,返回其他类型会抱错。还有一个需要注意的是,__str__的用户友好显示可能只有对象出现在一个打印操作的顶层时候才应用,嵌套 到较大对象中 的对象 可能用其__repr__或默认方法打印。

                例如:

                class  Printer:

                                def __init__(self,val):

                                                self.val = val

                                def __str__(self):

                                                return str(self.val)

                obj = [Printer(2),Printer(3)]

                for x in obj:

                                print(x)  #输出:2 3

                print(obj)  #输出:[<__main__.Printer object at 0xb73c808c>, <__main__.Printer object at 0xb73c80ac>]

                但是__repr__能够解决前面提的那个问题

                class  Printer:

                                def __init__(self,val):

                                                self.val = val

                                def __repr__(self):

                                                return str(self.val)

                obj = [Printer(2),Printer(3)]

                for x in obj:

                                print(x)  #输出:2 3

                print(obj)  #输出:2,3

3、右侧加法和原处加法:__radd__,__iadd__

                class adder:

                                def __init__(self,value=0):

                                                self.data = value

                                def __add__(self,,other):

                                                self.data+=other

                adder只是在+左边是对象时使用,如果要支持右侧使用实例对象,则需要重载 __radd__.

                例如:

                class Commuter:

                def __init__(self,val):

                                self.val = val

                def __add__(self,other):

                                print('add',self.val,other)

                                return self.val+other

                def __radd__(self,other):

                                print('radd',self.val,other)

                                return other+self.val   #这个 顺序无所谓,只是在调用的时候很位置很重要

                x = Commuter(88)

                y = Commuter(99)

                print(x+1)

                print('#'*8)

                print(1+y)

                print('$'*8)

                print(x+y)

                #输出结果如下:

                add 88 1

                89

                ########

                radd 99 1

                100

                $$$$$$$$

                add 88 <__main__.Commuter object at 0xb71e8c2c>

                radd 99 88

                187

               

                原处加法: __iadd__或者__add__但是__iadd__更高效

                class Number:

                                def __init__(self,val):

                                                self.val = val

                                def __iadd__(self,other):

                                                self.val+=other

                                                return self

                x = Number(5)

                x+=1

                x+=1

                print(x.val)  #输出:7

                或者

                class Number:

                                def __init__(self,val):

                                                self.val = val

                                def __add__(self,other):

                                                return Number(self.val+other)

4、call表达式:__call__  

                有关python的__call__在官方文档上有这么一句解释 (http://docs.python.org/reference/datamodel.html?highlight=__call__#object.__call__)

                object.__call__(self[, args...])

                Called when the instance is “called” as a function; if this method is defined, x(arg1, arg2, ...) is a shorthand for x.__call__(arg1, arg2, ...).

                当把一个实例当作方法来调用的时候,形如instance(arg1,args2,...),那么实际上调用的就是 instance.__call__(arg1,arg2,...)

                例如:

                class Prod:

                def __init__(self,value):

                                self.value = value

                def __call__(self,other):

                                return self.value *other

                x = Prod(2)

                print(x(3))  #输出:6

5、比较:__lt__,__gt__和其他方法

                比较运算没有位置限制。

                比较运算没有隐士关系,比如说 == 为真并不以为着 !=为假

                python2.6中如果没有定义更为具体的比较方法,对其使用一个__cmp__或者内置cmp函数。

                cmp( x, y)

                Compare the two objects x and y and return an integer according to the outcome. The return value is negative if x < y, zero if x == y and strictly positive if x > y.

               

                class C:

                def  __init__(self,data):

                                self.data = data

                def __gt__(self,other):

                                return self.data > other

                def __lt__(self,other):

                                return self.data < other

                x = C('spam')

                print('1',x >'ham')

                print('2','ham'> x)

                print('3',x < 'ham')

                print('4','ham' <x)

                y = C('ham')

                print('5',x<y)

                print('6',x>y)

6、布尔测试:__bool__,__len__

                在布尔环境中,python首先尝试__bool__来获取一个直接布尔值,然后如果没有该方法,就尝试__len__类根据对象的长度确定 一个真值。

7、对象析构函数:__del__

                每当实例产生时,就会调用__init__构造函数,每当 实例空间被回收时,就会执行析构函数。

                class Life:

                                def __init__(self,name='unknow'):

                                                print('hello ',name)

                                                self.name = name

                                def __del__(self):

                                                print('Goodbye',self.name)

                brain = Life('Brain')#输出 hello brain

                brain = 'loretta'   #输出: Goodbye brain