【问题标题】:How does polymorphism work in Python?多态性在 Python 中是如何工作的?
【发布时间】:2011-02-19 14:49:12
【问题描述】:

我是 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 is an animal 和 是一只狗。但我的输出是:

False
True

我错过了什么?

【问题讨论】:

  • 请注意,检查对象的类型与多态性相反。多态性对对象进行操作,无论其类型如何。
  • 这个问题的前提是误解:isinstance(myDog, animal) 做了你想要的,myDog.__class__ is animal 是错误的。同样在 Python 中,我们使用 MixedCase 作为类名,而使用 lower_case_with_underscores 作为对象名。所以你的类应该被称为Animal, Dog 和你的对象my_dog, dog1 等等。
  • 真的你的问题标题应该是“如何测试一个对象是否是指定类或其子类的实例?” 但是检查一个对象的类与多态性相反,正如@dash-tom-bang 所说,它依赖于方法的存在、实现和做适当的事情(或引发适当的异常)。
  • @anjaneyulubatta505 链接失效。

标签: python polymorphism


【解决方案1】:

Python 中的is 运算符检查两个参数是否引用了内存中的同一个对象;它不像 C# 中的 is 运算符。

From the docs:

运算符 is 和 is not 测试对象身份:当且仅当 x 和 y 是同一个对象时,x 是 y 为真。 x is not 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 理解继承并没有错,但在“生产”代码中通常应避免使用。

【讨论】:

  • 对于继承自 object 的类,您还可以查看 classname.__mro__ 元组,但实际上,这对教育目的更有用。
【解决方案2】:

分别尝试isinstance(myDog, dog)isinstance(myDog, animal).

【讨论】:

    【解决方案3】:

    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)
    

    【讨论】:

    • 也称为duck狗打字。
    【解决方案4】:

    只是一个很好的例子,如何使用 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
    

    【讨论】:

      猜你喜欢
      • 2012-06-16
      • 1970-01-01
      • 2015-10-10
      • 2020-12-27
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      • 2020-07-24
      • 2018-04-18
      相关资源
      最近更新 更多