多态如何在Python中工作?

时间:2010-05-14 16:23:42

标签: python polymorphism

我是Python新手......并且来自大多数Java背景,如果它可以解释任何问题。

我正在尝试理解Python中的多态性。也许问题是我期待我已经知道的概念投射到Python中。但我把以下测试代码放在一起:

class animal(object):
    "empty animal class"

class dog(animal):
    "empty dog class"

myDog = dog()
print myDog.__class__ is animal
print myDog.__class__ is dog

从我习惯的多态性(例如java的instanceof),我希望这两个语句都打印为true,因为dog 的一个实例是动物,而且< em>是一只狗。但我的输出是:

False
True

我错过了什么?

4 个答案:

答案 0 :(得分:72)

Python中的is运算符检查两个参数是否指向内存中的同一对象;它与C#中的is运算符不同。

From the docs

  

运算符是和不测试对象标识:当且仅当x和y是同一个对象时,x是y才为真。 x不是y产生反向真值。

在这种情况下,您需要的是isinstance

  

如果object参数是classinfo参数的实例,或者是(直接或间接)子类的实例,则返回true。

>>> class animal(object): pass

>>> class dog(animal): pass

>>> myDog = dog()
>>> isinstance(myDog, dog)
True
>>> isinstance(myDog, animal)
True

然而,惯用Python规定你(几乎)从不进行类型检查,而是依靠duck-typing进行多态行为。使用isinstance来理解继承没有错,但在“生产”代码中通常应该避免使用它。

答案 1 :(得分:41)

phimuemue和Mark已经回答了你的问题。但这也是Python中多态性的一个例子,但它并不像基于继承的示例那样明确。

class wolf(object): 
    def bark(self):
        print "hooooowll"

class dog(object): 
    def bark(self):
        print "woof"


def barkforme(dogtype):
    dogtype.bark()


my_dog = dog()
my_wolf = wolf()
barkforme(my_dog)
barkforme(my_wolf)

答案 2 :(得分:11)

尝试isinstance(myDog, dog) resp。 isinstance(myDog, animal)

答案 3 :(得分:0)

一个很好的例子,说明如何使用2个完全不同的类的相同字段。它更接近模板。

class A:
    def __init__(self, arg = "3"):
        self.f = arg
a = A()
a.f # prints 3
class B:
    def __init__(self, arg = "5"):
        self.f = arg
b = B()
b.f # prints 5


def modify_if_different(s,t, field):
    if s.__dict__[field] != t.__dict__[field]:
        t.__dict__[field]  = s.__dict__[field]
    else:
        s.__dict__[field]  = None

modify_if_different(a,b,"f")
b.f # prints 3
a.f # prints 3