课程:《Python编程基础》
主讲人:冯杰
还记得类(Class)吗?它像一个“收纳盒”,把数据和行为封装在一起。
class Car:
def __init__(self, brand):
self.brand = brand
self._speed = 0
def speed_up(self):
self._speed += 10
print(f"{self.brand} 正在加速...")
但如果想造一辆“电动汽车”呢?
这就引出了... 继承!
继承允许子类获取父类的所有功能,并进行扩展。这是代码复用的利器!
电动汽车 “是”一种 汽车
# ElectricCar 继承自 Car
class ElectricCar(Car):
def __init__(self, brand, battery_size):
# 注意这里!我们用 super() 调用了父类的初始化方法
super().__init__(brand)
self.battery_size = battery_size
def charge(self):
print(f"正在为 {self.brand} 充电...")
super()
是什么?它是连接子类与父类的“超级纽带”。
当我们重写一个方法时(比如 __init__
),用它来调用父类的版本,可以避免重复代码,并确保父类的初始化等重要逻辑不会被漏掉。
class Parent:
def greet(self):
print("Hello from Parent")
class Child(Parent):
def greet(self):
print("Message from Child")
# super() 保证了父类的 greet() 也会被调用
super().greet()
c = Child()
c.greet()
# 输出:
# Message from Child
# Hello from Parent
如何判断一个对象的类型?isinstance()
是更好的选择,因为它尊重继承关系。
my_tesla = ElectricCar("Tesla", 75)
# 方式一:type() - 检查是否“一模一样” (不推荐)
print(f"type(my_tesla) == Car: {type(my_tesla) == Car}") # False
# 方式二:isinstance() - 检查“是不是一种” (推荐)
print(f"isinstance(my_tesla, Car): {isinstance(my_tesla, Car)}") # True
结论:在面向对象的代码中,总是优先使用 isinstance()
。
多态指“多种形态”,即同一指令,不同表现。这是程序灵活性的关键。
比如,所有车都需要“补充能源”,但方式不同:
class GasolineCar(Car):
def refuel(self):
print("加95号汽油。")
class ElectricCar(Car):
def refuel(self):
print("正在充电。")
我们写一个通用函数,它不关心车的具体类型,只管调用 `refuel` 方法。
# 这个函数能处理任何有 refuel 方法的对象
def service_vehicle(vehicle):
print(f"--- {vehicle.brand} 进入服务站 ---")
vehicle.refuel()
# 创建不同类型的对象
tesla = ElectricCar("Tesla", 75)
porsche = GasolineCar("Porsche 911")
# 用同一个函数处理它们!
service_vehicle(tesla) # -> 输出: 正在充电。
service_vehicle(porsche) # -> 输出: 加95号汽油。
"如果一个东西走起来像鸭子,叫起来也像鸭子,那它就是一只鸭子。"
Python不关心对象的类型,只关心它能做什么。多态不一定需要继承!
class Dog:
def speak(self): return "Woof!"
class Person:
def speak(self): return "Hello!"
# 这个函数只要求对象有 .speak() 方法
def make_it_speak(entity):
print(entity.speak())
make_it_speak(Dog()) # -> Woof!
make_it_speak(Person()) # -> Hello!
顶尖AI项目 vLLM 就大量运用了这些思想来管理不同的大模型。
# 1. 定义一个通用的基类
class LLM:
def generate(self, prompt): ...
# 2. Llama模型继承LLM,并重写generate方法 (继承)
class LlamaForCausalLM(LLM):
def generate(self, prompt):
# Llama专属的优化逻辑...
print("调用Llama专属逻辑...")
# 3. 框架代码统一处理所有LLM模型 (多态)
def run_model(model: LLM, text):
model.generate(text)
my_llama = LlamaForCausalLM()
run_model(my_llama, "你好") # -> 会自动调用Llama的专属代码!
当你调用一个方法时,Python如何查找它?它会遵循一个清晰、可预测的顺序,即 MRO。
# 我们可以用 .mro() 来查看这个顺序
print(ElectricCar.mro())
# 输出:
# [
# <class '__main__.ElectricCar'>,
# <class '__main__.Car'>, # 1. 先找自己
# <class 'object'> # 2. 再找父类... 直到始祖 object
# ]
super()
函数就是沿着这个顺序去查找下一个方法的。
super()
妙用isinstance
, MRO感谢聆听!
本课程由 Google Gemini 协同制作
部分内容参考了廖雪峰Python教程