python中的多态

何为多态?


按照松本行弘的说法,多态就是把不同种类的东西当做相同的东西来处理。多态(面向对象)的本质是消息传递。由编译器向实例传递不同的消息来使之进行不同的操作。消息体为传递的方法名、参数个数以及类型等。在没有多态的支持下编程类似这样:

1
2
3
4
5
6
7
def method():
if arg is type of TypeA:
...
elif arg is type of TypeB:
...
else:
...

如果存在多态,编程类似这样

1
2
3
4
5
6
7
8
def method(TypeA arg):
...
def method(TypeB arg):
...
def method(TypeA arga, TypeB argb):
...

由编译器来自动将参数arg分派给正确的方法进行调用。

python中的多态?


从上面的例子可以看到,要想支持多态需要python解释器能够区分不同类型的参数(参数的个数比较好容易区别)。
而动态语言要想做到这一点比较困难(如果做到这一点就不是动态语言了)。所以,python是不支持完整的多态的(可以利用语法部分实现多态的功能)。

如何实现类似多态的支持?


python支持duck typing和多参数,所以部分补偿了不支持多态的问题(按照python老爹的说法,多态不是程序员真正需要的)。当然,多态是语法糖果,即使没有多态也能完成程序。不过在这里只讨论实现类似多态的办法,即方法名相同,不同类型和参数个数的调用。

  • 方法之一,使用if...elif...else*args
1
2
3
4
5
6
7
8
9
10
class Poly(object):
def method(self, *args): #def method(self, arga=None, argb=None)
arga = args.get('arga', None)
argb = args.get('argb', None)
if arga and argb:
...
elif arga:
...
elif argb:
...

即利用 *args 不定参数来实现 或者

1
2
3
4
5
6
class Poly(object):
def method(self, arg):
if type(arg) == TypeA:
....
elif type(arg) == TypeB:
....

显式进行类型判断再分派(不是好的办法)。

  • 方法二, 使用设计模式。将对不同对象(类型)的操作隐藏在操作对象中。
1
2
3
4
5
6
7
8
9
10
11
class Context(object):
def method(self, obj):
obj.op(self)
class ArgA(object):
def op(self, context):
....
class ArgB(object):
def op(self, context):
...

将操作隐含在对象本身中。 因为类似策略模式所以使用了Context来表明类名称。但是,这种方法不支持不定参数个数的多态。

总结


在python中使用多态不是一种好的编程方法。