1. Python面向对象编程进阶:组合、方法与装饰器实战解析
面向对象编程(OOP)是Python开发中的核心技能,但很多开发者仅停留在基础的封装、继承、多态概念上。在实际项目中,真正决定代码质量的往往是那些进阶特性——如何优雅地复用代码?如何精细控制属性访问?如何设计合理的方法类型?这些才是区分"会用Python"和"精通Python"的关键。
我在多个大型Python项目中深刻体会到,合理运用组合模式、正确选择方法类型、巧妙使用property装饰器,能让代码的可维护性提升数倍。本文将结合实战案例,带你掌握这些进阶技巧。
1.1 组合模式:比继承更灵活的代码复用方案
1.1.1 组合与继承的本质区别
组合和继承是面向对象中两种不同的代码复用方式,它们最核心的区别在于类之间的关系:
- 继承(is-a):表示"是一个"的关系。比如"狗是动物"、"管理员是用户",子类是父类的一种具体类型
- 组合(has-a):表示"有一个"的关系。比如"汽车有发动机"、"老师有课程",一个对象包含另一个对象
python复制# 继承示例
class Animal: pass
class Dog(Animal): pass # Dog is a Animal
# 组合示例
class Engine: pass
class Car:
def __init__(self):
self.engine = Engine() # Car has a Engine
1.1.2 组合模式的三大优势
- 低耦合:组合的类之间相互独立,修改一个类不会影响另一个类
- 高灵活:可以在运行时动态添加或移除组件
- 易扩展:新增功能只需创建新类,无需修改现有类结构
1.1.3 实战案例:教师课程管理系统
让我们通过一个完整的教师-课程管理系统来理解组合模式的实际应用:
python复制class Course:
"""课程类,可被多个其他类复用"""
def __init__(self, name, price, duration):
self.name = name
self.price = price
self.duration = duration
def show_info(self):
return f"《{self.name}》价格:{self.price}元,时长:{self.duration}月"
class Teacher:
"""教师类,通过组合方式关联课程"""
def __init__(self, name, subject):
self.name = name
self.subject = subject
self.courses = [] # 组合核心:存储Course实例
def add_course(self, course):
if not isinstance(course, Course):
raise TypeError("必须传入Course实例")
self.courses.append(course)
print(f"{self.name}老师添加了课程:{course.name}")
def show_all_courses(self):
print(f"\n{self.name}老师({self.subject})的授课列表:")
for idx, course in enumerate(self.courses, 1):
print(f"{idx}. {course.show_info()}")
# 使用示例
math_teacher = Teacher("张老师", "数学")
python_course = Course("Python基础", 1999, 3)
math_course = Course("高等数学", 1599, 4)
math_teacher.add_course(python_course)
math_teacher.add_course(math_course)
math_teacher.show_all_courses()
关键设计原则:Course类保持独立,任何需要关联课程的类(如Student)都可以直接组合它,无需重复实现课程相关逻辑。
1.1.4 组合与继承的选择标准
| 场景特征 | 推荐方式 | 示例 |
|---|---|---|
| 需要表达"是一种"关系 | 继承 | 管理员是用户的一种 |
| 需要表达"有一部分"关系 | 组合 | 汽车有发动机 |
| 需要复用实现代码 | 继承 | 子类复用父类方法 |
| 需要复用独立功能 | 组合 | 多个类共享日志模块 |
| 关系在运行时可能变化 | 组合 | 动态添加插件 |
| 需要多态特性 | 继承 | 统一接口不同实现 |
1.2 方法类型详解:对象方法、类方法与静态方法
1.2.1 三种方法类型对比
Python类中的方法主要分为三种类型,它们在使用场景和调用方式上有显著区别:
| 方法类型 | 装饰器 | 绑定对象 | 第一个参数 | 典型应用场景 |
|---|---|---|---|---|
| 对象方法 | 无 | 实例 | self | 操作实例属性 |
| 类方法 | @classmethod | 类 | cls | 操作类属性、工厂模式 |
| 静态方法 | @staticmethod | 无 | 无 | 工具函数 |
1.2.2 对象方法:实例专属操作
对象方法是最常用的方法类型,用于操作特定实例的属性:
python复制class Student:
def __init__(self, name):
self.name = name
def greet(self): # 对象方法
print(f"你好,我是{self.name}")
stu = Student("小明")
stu.greet() # 输出:你好,我是小明
关键点:
- 必须通过实例调用
- 可以访问和修改实例属性(self.xxx)
- 每个实例调用方法时操作的是自己的数据
1.2.3 类方法:类级别操作
类方法用于操作类级别的属性和行为:
python复制class Student:
school = "第一中学" # 类属性
@classmethod
解锁全文
加入我们的会员,获取最新、最热、最精彩的开发者技术内容