ARTICLE DETAIL

资讯详情

深耕网站SEO优化与搜索引擎排名提升的一线实战洞察。

Python 中的多态,不止是“重写”——聊聊鸭子类型与动态协议

Python 中的多态,不止是“重写”——聊聊鸭子类型与动态协议 一、传统多态 vs Python 多态在编译型语言如 Java中多态通常通过继承 方法重写override和方法重载overload来实现。编译器会在编译期检查方法签名确保子类正确覆写了父类方法或者同一个类中有多个同名但参数不同的方法。但在 Python 中没有方法重载同名方法只能有一个也不强制子类重写父类方法。那么 Python 的多态体现在哪里其实Python 更关注对象的行为而不是对象的类型。只要一个对象拥有某个方法我们就可以调用它——这就是鸭子类型Duck Typing“如果它走起来像鸭子叫起来像鸭子那么它就是鸭子。”二、代码实战一个函数多种飞翔class Bird: def fly(self): print(鸟在飞) class Airplane: def fly(self): print(飞机在飞) class Dog: def fly(self): print(狗在飞哈哈被抛起来的) class Cat: pass # 没有 fly 方法 def start_flying(obj): obj.fly() # 只要对象有 fly() 即可不关心类型 start_flying(Bird()) # 鸟在飞 start_flying(Airplane()) # 飞机在飞 start_flying(Dog()) # 狗在飞 # start_flying(Cat()) # 报错 AttributeError因为 Cat 没有 fly三、专业术语解析运行时多态Runtime Polymorphism方法调用在运行时才确定具体调用哪个实现Python 天生如此。协议Protocol在 Python 中协议是一种非正式接口例如“可迭代协议”要求实现__iter__“上下文协议”要求实现__enter__和__exit__。fly方法也是一种自定义协议。动态类型Dynamic Typing变量无需声明类型解释器在运行时检查对象是否有对应属性。EAFPEasier to Ask for Forgiveness than PermissionPython 编程风格——直接尝试调用如果出错再捕获异常而不是事先用isinstance检查类型。四、与多态相关的代码补充在提供的86.多态.py中还演示了在同一个类内通过*args模拟方法重载以及子类重写父类方法的经典方式class Person: def get_info(self, *args): # 可变参数实现“多参”效果 for p in args: print(p) class SupperPerson(Person): def get_info(self): # 重写父类方法 return self.__str__()这种方式虽然不像真正的重载那样严谨但足够灵活满足业务需求。五、总结Python 的多态不依赖继承体系而是依赖对象是否实现了所需的方法。鸭子类型让代码更简洁、更通用但也需要开发者对“协议”有清晰认知。编写函数时尽量接受“任意对象”只要求它具备某些方法这样代码复用性更高。下篇预告如何强制子类实现某个方法抽象基类ABC来帮忙。
返回列表