Python类和方法_运算符重载与对象类型运算

一,运算符重载

如果通过定义一些特定的方法,就能针对自定义类型,让运算符有特定的作用。

比如,如果你在 Time 类中定义了一个名为add的方法,你就可以对 Time 对象使用 + 加号运算符。

>>> class Time:

...       def __init__(self, hour=0, minute=0, second=0):

...           self.hour = hour

...           self.minute = minute

...           self.second = second

...       def __str__(self):

...           return '%.2d:%.2d:%.2d' % (self.hour, self.minute, self.second)

...       def time_to_int(time):

...           minutes = time.hour * 60 + time.minute

...           seconds = minutes * 60 + time.second

...           return seconds

...       def int_to_time(self, seconds):         //这里是交互模式,不需要写入self,如果写到脚本里,要加self

...           time = Time()

...           minutes, time.second = divmod(seconds, 60)

...           time.hour, time.minute = divmod(minutes, 60)

...           return time

...       def __add__(self, other):

...           seconds = self.time_to_int() + other.time_to_int()

...           return self.int_to_time(seconds)       //这里是交互模式,不需要写入self,如果写到脚本里,要加self。

... 

>>> start = Time(1, 20)

>>> duration = Time(2, 30)

>>> print(start + duration)

03:50:00

当你针对 Time 对象使用加号运算符的时候,Python 就会调用自定义的 add 方法。当用 print 输出结果的时候,Python 就会调用自定义的 str 方法。

针对用户自定义类型,让运算符有相应的行为,这就叫做运算符重载。Python 当中每一个运算符都有一个对应的方法,比如这里的add。

二,根据对象类型进行运算

1.我们可以把两个 Time 对象进行相加,但也许有时候需要把一个整数加到 Time 对象上面。

下面这一个版本的add方法就能够实现检查类型,然后调用add_time 方法或者是 increment 方法:

$ cat c.py

#!/bin/python

 class Time:

    def __init__(self, hour=0, minute=0, second=0):

        self.hour = hour

        self.minute = minute

        self.second = second

    def __str__(self):

        return '%.2d:%.2d:%.2d' % (self.hour, self.minute, self.second)

    def time_to_int(time):

        minutes = time.hour * 60 + time.minute

        seconds = minutes * 60 + time.second

        return seconds

    def int_to_time(self, seconds):

        time = Time()

        minutes, time.second = divmod(seconds, 60)

        time.hour, time.minute = divmod(minutes, 60)

        return time

    def __add__(self, other):

        if isinstance(other, Time):

            return self.add_time(other)

        else:

            return self.increment(other)

    def add_time(self, other):

        seconds = self.time_to_int() + other.time_to_int()

        return self.int_to_time(seconds)

    def increment(self, seconds):

        seconds += self.time_to_int()

        return self.int_to_time(seconds)   

内置函数isinstance 接收一个值和一个类的对象,如果该值是这个类的一个实例,就会返回真。

如果拿来相加的是一个 Time 对象,add就会调用 add_time 方法;其他情况下,程序会把参数当做一个数字,然后就调用 increment 方法。

这种运算就是根据对象进行的,因为在针对不同类型参数的时候,运算符会进行不同的计算。

下面的例子中,就展示了用不同类型变量来相加的效果:

>>> start = Time(1, 20)
>>> duration = Time(2, 30)
>>> print(start + duration)
03:50:00
>>> print(start + 1437) 

01:43:57

2.其实,上面的这个加法运算不满足交换率,如果整数放到首位,就会得到如下所示的错误了:

>>> print(1437 + start) 

Traceback (most recent call last):

  File "c.py", line 35, in <module>

    print(1437 + start)

TypeError: unsupported operand type(s) for +: 'int' and 'Time'

这里的问题就在于,Python 并没有让一个 Time 对象来加一个整数,而是去调用了整形的加法,然后把一个 Time 对象加到整数上面去,这就是用系统原本的加法,但这个加法不能处理 Time 对象。

针对这个问题,我们可以运用一个特殊的方法radd;这个方法的意思就是“右加”,即当一个 Time 对象出现在加号运算符右侧的时候,该方法就会被调用了。

在Time类定义里加入radd方法:

    def __radd__(self, other):

        return self.__add__(other) 

然后把数字放到前面,再次打印就没有问题了:

>>> print(1337 + start)

01:43:57

结束。
原文地址:https://www.cnblogs.com/liusingbon/p/13306635.html