python如何实现多态
python如何实现多态
继承和方法重写:
子类继承父类的方法,并在子类中重写特定方法来实现不同的行为。
class Parent:
pass
class Child(Parent):
pass
class OtherClass:
pass
def check_subclass_and_parent(obj, cls, expected_parent):
if not isinstance(obj, cls):
return False
# 检查父类是否与预期的父类相同
actual_parent = obj.__class__.__bases__[0]
return actual_parent == expected_parent
parent_obj = Parent()
child_obj = Child()
other_obj = OtherClass()
print(check_subclass_and_parent(child_obj, Parent, Parent))
print(check_subclass_and_parent(other_obj, Parent, Parent))
鸭子类型:
只要对象具有特定的行为(方法或属性),就可以视为具有某种类型,而不需要明确的继承关系。
在Python中,鸭子类型(Duck Typing)是一种动态类型检查的概念,它的核心思想是:“如果它看起来像鸭子,游起来像鸭子,那么它就是鸭子”。这意味着一个对象的适用性不是由它的类型决定的,而是由它的属性和方法决定的。在Python中,鸭子类型是自然支持的,因为Python是一种动态类型语言,不需要显式声明变量的类型。
以下是一些实现鸭子类型的方法:
1. 检查对象的方法或属性
在调用对象的方法或属性之前,你可以检查它是否存在:
def quack_and_fly(bird):
if hasattr(bird, 'quack') and callable(bird.quack):
bird.quack()
if hasattr(bird, 'fly') and callable(bird.fly):
bird.fly()
class Duck:
def quack(self):
print("Quack, quack!")
def fly(self):
print("Flap, flap!")
class Person:
def quack(self):
print("The person imitates a duck.")
def fly(self):
print("The person waves their arms and pretends to fly.")
duck = Duck()
person = Person()
quack_and_fly(duck) # 输出:Quack, quack! Flap, flap!
quack_and_fly(person) # 输出:The person imitates a duck. The person waves their arms and pretends to fly.
2. 使用try
和except
捕获异常
另一种方法是尝试调用方法或属性,并在失败时捕获异常:
def quack_and_fly(bird):
try:
bird.quack()
except AttributeError:
print("Sorry, this bird can't quack.")
try:
bird.fly()
except AttributeError:
print("Sorry, this bird can't fly.")
# 使用相同的Duck和Person类
quack_and_fly(duck) # 输出:Quack, quack! Flap, flap!
quack_and_fly(person) # 输出:The person imitates a duck. The person waves their arms and pretends to fly.
3. 使用collections.abc
模块
从Python 3.3开始,可以使用collections.abc
模块来定义抽象基类(ABCs),这样可以在不显式检查属性或方法的情况下实现鸭子类型:
from abc import ABC, abstractmethod
class Quackable(ABC):
@abstractmethod
def quack(self):
pass
class Flyable(ABC):
@abstractmethod
def fly(self):
pass
def quack_and_fly(bird):
if isinstance(bird, Quackable):
bird.quack()
if isinstance(bird, Flyable):
bird.fly()
# 使用相同的Duck和Person类
quack_and_fly(duck) # 输出:Quack, quack! Flap, flap!
quack_and_fly(person) # 不会输出,因为person不是Quackable或Flyable的实例
函数参数的多态性:
函数可以接受不同类型的对象,并根据对象的实际类型执行相应的操作。
在Python中,函数参数的多态性指的是函数可以接受不同类型的参数,并且能够根据参数的类型以不同的方式处理它们。
这种多态性使得同一个函数可以适用于多种不同的数据类型,增加了代码的灵活性和可重用性。Python中的函数参数多态性主要通过以下几种方式实现:
1. 位置参数(Positional Arguments)
函数可以被设计为接受任意数量的位置参数,这些参数在调用时不需要指定名称:
def print_items(*args):
for item in args:
print(item)
print_items(1, 'two', 3.0, 'four') # 输出:1 two 3.0 four
2. 关键字参数(Keyword Arguments)
关键字参数允许函数接受任意数量的命名参数,这些参数在调用时必须指定名称:
def print_kwargs(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_kwargs(name="Alice", age=30, city="Wonderland") # 输出:name: Alice age: 30 city: Wonderland
3. 可变位置参数和关键字参数
结合使用位置参数和关键字参数,函数可以接受任意数量的位置参数和关键字参数:
def print_all(*args, **kwargs):
for item in args:
print(item)
for key, value in kwargs.items():
print(f"{key}: {value}")
print_all(1, 'two', 3.0, name="Alice", age=30) # 输出:1 two 3.0 name: Alice age: 30
4. 类型检查和转换
在函数内部,可以检查参数的类型,并根据需要进行转换或处理:
def add(a, b):
if isinstance(a, str) and isinstance(b, str):
return a + b
else:
return float(a) + float(b)
print(add("hello, ", "world")) # 输出:hello, world
print(add(5, 3)) # 输出:8.0