Python类和方法_多态

一,多态

在必要的时候,根据类型运算还是很有用的,不过并不总需要这么做。一般情况下,我们都可以把函数写成能处理不同类型参数的,这样就不用这么麻烦了。

之前为字符串写的很多函数,也都可以用到其他序列类型上面。比如用函数 histogram 来统计一个单词中每个字母出现的次数。

>>> def histogram(s):

...     d = dict()

...     for c in s:

...         if c not in d:

...            d[c] = 1

...         else:

...            d[c] = d[c]+1

...     return d

... 

这个函数也可以用于列表、元组,甚至字典,只要 s 的元素是散列的,就能用做 d 当中的键。

>>> t = ['spam', 'egg', 'spam', 'spam', 'bacon', 'spam']

>>> histogram(t)

{'spam': 4, 'egg': 1, 'bacon': 1}

像上述函数histogram这样,针对不同类型都可以运行的函数,就是多态了。

多态能够有利于代码复用,比如内置的函数 sum,是用来把一个序列中所有的元素加起来,就可以适用于所有能够相加的序列元素。

现在 Time 对象有了自己的加法方法,就可以与 sum 函数来配合使用了:

$ 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)   

    def __radd__(self, other):

        return self.__add__(other) 

    def histogram(s):

        d = dict()

        for c in s:

            if c not in d:

                 d[c] = 1

            else:

                 d[c] = d[c]+1

        return d

t1 = Time(3, 30)

t2 = Time(3, 31)

t3 = Time(3, 32)

total = sum([t1, t2, t3])

print(total)

$ python3 c.py

10:33:00

总的来说,如果一个函数内的所有运算都可以处理某一类型,这个函数就适用于这一类型了。

二,调试

在程序运行的任意时刻都可以给对象增加属性,不过如果你有多个同类对象却又不具有相同的属性,就容易出错了。

所以,最好在对象实例化的时候就全部用 init 方法初始化对象的全部属性。

如果你不确定一个对象是否有某个特定的属性,你可以用内置函数 vars,即一种读取属性的方法,

这个函数会接收一个对象,然后返回一个字典,字典中的键值对就是属性名的字符串与对应的值。

>>> class Point:

...       def __init__(self, x=0, y=0):

...           self.x = x

...           self.y = y

...       def __str__(self):

...           return '(%g, %g)' % (self.x, self.y)

... 

>>> p = Point(3, 4)

>>> vars(p)

{'x': 3, 'y': 4}

结束。

原文地址:https://www.cnblogs.com/liusingbon/p/13322713.html