多态性在 Python 中是如何工作的?

2022-01-24 00:00:00 python polymorphism

问题描述

我是 Python 的新手...并且主要来自 Java 背景,如果这说明了什么的话.

I'm new to Python... and coming from a mostly Java background, if that accounts for anything.

我正在尝试理解 Python 中的多态性.也许问题在于我希望将我已经知道的概念投射到 Python 中.但是我把下面的测试代码放在一起:

I'm trying to understand polymorphism in Python. Maybe the problem is that I'm expecting the concepts I already know to project into Python. But I put together the following test code:

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 的实例而且是一只狗.但我的输出是:

From the polymorphism I'm used to (e.g. java's instanceof), I would expect both of these statements to print true, as an instance of dog is an animal and also is a dog. But my output is:

False
True

我错过了什么?


解决方案

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

The is operator in Python checks that the two arguments refer to the same object in memory; it is not like the is operator in C#.

来自文档:

运算符 is 和 is not 测试对象身份:当且仅当 x 和 y 是同一个对象时,x 是 y 为真.x is not y 产生逆真值.

The operators is and is not test for object identity: x is y is true if and only if x and y are the same object. x is not y yields the inverse truth value.

在这种情况下,您要查找的是 isinstance.

What you're looking for in this case is isinstance.

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

Return true if the object argument is an instance of the classinfo argument, or of a (direct or indirect) subclass thereof.

>>> class animal(object): pass

>>> class dog(animal): pass

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

然而,惯用的 Python 要求您(几乎)从不进行类型检查,而是依赖 duck-为多态行为键入.使用 isinstance 来理解继承并没有错,但在生产"代码中通常应该避免使用它.

However, idiomatic Python dictates that you (almost) never do type-checking, but instead rely on duck-typing for polymorphic behavior. There's nothing wrong with using isinstance to understand inheritance, but it should generally be avoided in "production" code.

相关文章