Python 简明教程

Python - Polymorphism

What is Polymorphism in Python?

术语 polymorphism 指的是在不同上下文中采用不同形式的函数或方法。由于 Python 是动态类型语言,因此 Python 中的多态性很容易实现。

The term polymorphism refers to a function or method taking different forms in different contexts. Since Python is a dynamically typed language, polymorphism in Python is very easily implemented.

如果某个父类中的方法在它的不同子类中由不同的业务逻辑覆盖,则这个基类方法就是一个多态方法。

If a method in a parent class is overridden with different business logic in its different child classes, the base class method is a polymorphic method.

Ways of implementing Polymorphism in Python

有四种方法可以在 Python 中实现多态性 −

There are four ways to implement polymorphism in Python −

  1. Duck Typing

  2. Operator Overloading

  3. Method Overriding

  4. Method Overloading

ways to implement polymorphism

Duck Typing in Python

鸭子类型是一种概念,其中对象类型或类不如它定义的方法重要。使用此概念,只要该方法存在,就可以在对象上调用任何方法,而无需检查其类型。

Duck typing is a concept where the type or class of an object is less important than the methods it defines. Using this concept, you can call any method on an object without checking its type, as long as the method exists.

这个术语由一句很有名的引用来定义,叫做:假设有一只鸟像鸭子一样走路,像鸭子一样游泳,看起来像鸭子,并且嘎嘎叫,那么它很可能是一只鸭子。

This term is defined by a very famous quote that states: Suppose there is a bird that walks like a duck, swims like a duck, looks like a duck, and quaks like a duck then it probably is a duck.

Example

在下面给出的代码中,我们实际展示了鸭子类型的概念。

In the code given below, we are practically demonstrating the concept of duck typing.

class Duck:
   def sound(self):
      return "Quack, quack!"

class AnotherBird:
   def sound(self):
      return "I'm similar to a duck!"

def makeSound(duck):
   print(duck.sound())

# creating instances
duck = Duck()
anotherBird = AnotherBird()
# calling methods
makeSound(duck)
makeSound(anotherBird)

执行此代码时,将生成以下输出 −

When you execute this code, it will produce the following output −

Quack, quack!
I'm similar to a duck!

Method Overriding in Python

在方法重写中,在子类中定义的方法具有与其超类中的方法相同的名字,但实现了不同的功能。

In method overriding, a method defined inside a subclass has the same name as a method in its superclass but implements a different functionality.

Example

作为下面给出的多态性示例,我们有 shape ,它是一个抽象类。它被两个类 circle 和 rectangle 用作父类。这两个类以不同的方式重写了父级的 draw() 方法。

As an example of polymorphism given below, we have shape which is an abstract class. It is used as parent by two classes circle and rectangle. Both classes override parent’s draw() method in different ways.

from abc import ABC, abstractmethod
class shape(ABC):
   @abstractmethod
   def draw(self):
      "Abstract method"
      return

class circle(shape):
   def draw(self):
      super().draw()
      print ("Draw a circle")
      return

class rectangle(shape):
   def draw(self):
      super().draw()
      print ("Draw a rectangle")
      return

shapes = [circle(), rectangle()]
for shp in shapes:
   shp.draw()

Output

当运行以上代码时,它会产生以下输出 −

When you run the above code, it will produce the following output −

Draw a circle
Draw a rectangle

变量 shp 首先引用 circle 对象,并从 circle 类中调用 draw() 方法。在下一次迭代中,它引用 rectangle 对象,并从 rectangle 类中调用 draw() 方法。因此 shape 类中的 draw() 方法是多态的。

The variable shp first refers to circle object and calls draw() method from circle class. In next iteration, it refers to rectangle object and calls draw() method from rectangle class. Hence draw() method in shape class is polymorphic.

Overloading Operators in Python

假设你创建了一个表示二维向量的 Vector 类,当你使用加号运算符给它们相加时会发生什么?Python 很可能会向你大喊大叫。

Suppose you have created a Vector class to represent two-dimensional vectors, what happens when you use the plus operator to add them? Most likely Python will yell at you.

但是,您可以在自己的类中定义 add 方法来执行向量加法,然后加法运算符将按预期的那样执行 −

You could, however, define the add method in your class to perform vector addition and then the plus operator would behave as per expectation −

Example

class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b

   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)

   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

Vector(7,8)

Method Overloading in Python

当一个类包含两个或更多具有相同名称但不同参数数量的方法时,这种情况下可以称为方法重载。

When a class contains two or more methods with the same name but different number of parameters then this scenario can be termed as method overloading.

默认情况下,Python 不允许方法重载,但是我们可以使用可变长参数列表、多重派发和默认参数等技术来实现这一目标。

Python does not allow overloading of methods by default, however, we can use the techniques like variable-length argument lists, multiple dispatch and default parameters to achieve this.

Example

在下面的示例中,我们使用可变长参数列表来实现方法重载。

In the following example, we are using the variable-length argument lists to achieve method overloading.

def add(*nums):
   return sum(nums)

# Call the function with different number of parameters
result1 = add(10, 25)
result2 = add(10, 25, 35)

print(result1)
print(result2)

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

35
70