面向对象编程(OOP)是 Python 的核心范式,通过**类(Class)和实例(Instance)**将数据与操作封装为逻辑单元。本文将从基础概念到高级应用,系统讲解 Python 3 中类和实例的运作机制,并提供实践示例。
一、类与实例基础
1. 类的定义与实例化
- 定义类: 使用 class 关键字,首字母通常大写
- 构造函数:init 方法初始化实例属性
class Dog:
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age
def bark(self): # 实例方法
print(f"{self.name}:汪汪!")
# 创建实例
my_dog = Dog("阿黄", 3)
my_dog.bark() # 输出:阿黄:汪汪!
2. self 的含义
- 指向实例自身的引用,在方法调用时自动传入
- 方法定义必须显式声明 self 参数(约定名称,可改但强烈不建议)
二、属性与方法的类型
1. 实例属性与类属性
类型 | 定义位置 | 访问方式 | 特点 |
---|---|---|---|
实例属性 | __ init __ 或方法内 | self.属性名 | 每个实例独立拥有 |
类属性 | 类内部,方法外 | 类名.属性名 或 实例.属性名 | 所有实例共享,可被覆盖 |
class Student:
school = "第一中学" # 类属性
def __init__(self, name):
self.name = name # 实例属性
# 访问属性
stu1 = Student("小明")
print(stu1.school) # 第一中学(通过实例访问类属性)
print(Student.school) # 第一中学(通过类访问)
Student.school = "实验中学" # 修改类属性影响所有实例
print(stu1.school) # 实验中学
2. 实例方法、类方法与静态方法
方法类型 | 装饰器 | 首个参数 | 用途 |
---|---|---|---|
实例方法 | 无 | self | 操作实例属性 |
类方法 | @classmethod | cls | 操作类属性或创建工厂方法 |
静态方法 | @staticmethod | 无 | 与类相关但无需访问实例/类属性 |
class DateUtil:
date_format = "YYYY-MM-DD" # 类属性
def __init__(self, date_str):
self.date = date_str
# 实例方法:处理具体日期
def parse(self):
return self.date.split("-")
# 类方法:修改默认格式
@classmethod
def set_format(cls, new_format):
cls.date_format = new_format
# 静态方法:工具函数
@staticmethod
def is_leap_year(year):
return year % 400 == 0 or (year % 4 == 0 and year % 100 != 0)
# 使用示例
DateUtil.set_format("MM/DD/YYYY")
print(DateUtil.date_format) # MM/DD/YYYY
d = DateUtil("2023-08-15")
print(d.parse()) # ['2023', '08', '15']
print(DateUtil.is_leap_year(2024)) # True
三、封装与属性控制
1. 私有属性与名称改写
- 约定: 单下划线 _var 表示“受保护”,双下划线 __var 触发名称改写
- 实质: __var 会被改写为 _类名__var,非真正私有
class BankAccount:
def __init__(self, balance):
self.__balance = balance # 私有属性
def deposit(self, amount):
if amount > 0:
self.__balance += amount
def get_balance(self): # 通过方法访问私有属性
return self.__balance
account = BankAccount(1000)
# print(account.__balance) # 报错:AttributeError
print(account._BankAccount__balance) # 1000(不推荐直接访问)
2. 使用 @property 实现属性控制
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def diameter(self):
return 2 * self.radius
@diameter.setter
def diameter(self, value):
if value <= 0:
raise ValueError("直径必须为正数")
self.radius = value / 2
c = Circle(5)
print(c.diameter) # 10(自动计算)
c.diameter = 14 # 自动更新 radius
print(c.radius) # 7.0
四、继承与多态
1. 继承的基本语法
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("子类必须实现此方法")
class Cat(Animal):
def speak(self):
print(f"{self.name}:喵~")
class Dog(Animal):
def speak(self):
print(f"{self.name}:汪!")
animals = [Cat("小白"), Dog("小黑")]
for animal in animals:
animal.speak()
# 输出:
# 小白:喵~
# 小黑:汪!
2. 方法重写与 super()
class Vehicle:
def __init__(self, speed):
self.speed = speed
class Car(Vehicle):
def __init__(self, speed, wheels):
super().__init__(speed) # 调用父类初始化
self.wheels = wheels
car = Car(120, 4)
print(car.speed, car.wheels) # 120 4
五、特殊方法(魔术方法)
通过实现双下划线方法,自定义类的行为:
方法 | 作用 | 示例 |
---|---|---|
__ str __ | 定义 print() 的输出 | print(obj) |
__ repr __ | 定义解释器显示内容 | 直接输入 obj |
__ len __ | 定义 len(obj) 的返回值 | len(obj) |
__ add __ | 实现对象相加 | obj1 + obj2 |
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(1, 4)
print(v1 + v2) # Vector(3, 7)
六、最佳实践与常见陷阱
1. 避免的常见错误
-
可变类属性: 所有实例共享同一引用
# 错误示例 class Team: members = [] # 所有实例共享同一列表! t1 = Team() t1.members.append("Alice") t2 = Team() print(t2.members) # ['Alice'](非预期结果) # 正确做法:在 __init__ 中初始化 class Team: def __init__(self): self.members = []
-
过度使用继承: 优先选择组合而非继承
2. 设计建议
- 单一职责原则: 一个类只做一件事
- 使用属性验证(如 @property)
- 优先定义公开方法,隐藏实现细节
- 为类和方法添加文档字符串
class User:
"""用户实体类,存储用户基本信息"""
def __init__(self, name):
"""初始化用户对象"""
self.name = name
七、总结
类和实例是 Python 面向对象编程的基石:
- 封装: 通过类组织数据与行为
- 继承: 实现代码复用与层次化设计
- 多态: 统一接口处理不同对象
- 灵活性: 魔术方法允许自定义类型行为
掌握这些概念后,可进一步探索:
- 抽象基类(ABC): 定义接口规范
- 元类编程: 控制类的创建过程
- 设计模式: 如工厂模式、观察者模式等
通过面向对象编程,开发者能构建出模块化、易扩展的大型应用。尝试将你的下一个脚本重构为类结构,体验 OOP 带来的代码组织优势吧!