一,多态
在必要的时候,根据类型运算还是很有用的,不过并不总需要这么做。一般情况下,我们都可以把函数写成能处理不同类型参数的,这样就不用这么麻烦了。
之前为字符串写的很多函数,也都可以用到其他序列类型上面。比如用函数 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}
结束。