我是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
我错过了什么?
答案 0 :(得分:72)
Python中的is
运算符检查两个参数是否指向内存中的同一对象;它与C#中的is
运算符不同。
运算符是和不测试对象标识:当且仅当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