学习目标
通过本章学习,你将掌握: - 类和对象的基本概念 - 属性和方法的定义与使用 - 继承、封装、多态的实现 - 特殊方法(魔术方法)的使用 - 类的高级特性和设计模式 - 抽象类和接口的实现
7.1 类和对象基础
类的定义和实例化
# 基本类定义
class Person:
"""人员类"""
# 类变量(所有实例共享)
species = "Homo sapiens"
population = 0
def __init__(self, name, age):
"""构造方法"""
# 实例变量(每个实例独有)
self.name = name
self.age = age
Person.population += 1 # 更新人口计数
def introduce(self):
"""自我介绍方法"""
return f"我是{self.name},今年{self.age}岁"
def have_birthday(self):
"""过生日方法"""
self.age += 1
return f"{self.name}过生日了,现在{self.age}岁"
@classmethod
def get_population(cls):
"""类方法:获取人口数量"""
return cls.population
@staticmethod
def is_adult(age):
"""静态方法:判断是否成年"""
return age >= 18
print("=== 类和对象基础 ===")
# 创建实例
person1 = Person("Alice", 25)
person2 = Person("Bob", 17)
# 访问实例变量和方法
print(person1.introduce())
print(person2.introduce())
# 调用实例方法
print(person1.have_birthday())
# 访问类变量
print(f"物种: {Person.species}")
print(f"人口数量: {Person.get_population()}")
# 调用静态方法
print(f"Alice是否成年: {Person.is_adult(person1.age)}")
print(f"Bob是否成年: {Person.is_adult(person2.age)}")
# 动态添加属性
person1.email = "alice@example.com"
print(f"Alice的邮箱: {person1.email}")
# 查看实例属性
print(f"person1的属性: {vars(person1)}")
print(f"person2的属性: {vars(person2)}")
属性访问控制
class BankAccount:
"""银行账户类"""
def __init__(self, account_number, initial_balance=0):
self.account_number = account_number # 公开属性
self._balance = initial_balance # 受保护属性(约定)
self.__pin = "1234" # 私有属性(名称改写)
self.__transaction_history = [] # 私有属性
def deposit(self, amount):
"""存款"""
if amount > 0:
self._balance += amount
self.__add_transaction("存款", amount)
return f"存款成功,余额: {self._balance}"
return "存款金额必须大于0"
def withdraw(self, amount, pin):
"""取款"""
if not self.__verify_pin(pin):
return "PIN码错误"
if amount <= 0:
return "取款金额必须大于0"
if amount > self._balance:
return "余额不足"
self._balance -= amount
self.__add_transaction("取款", amount)
return f"取款成功,余额: {self._balance}"
def get_balance(self, pin):
"""查询余额"""
if self.__verify_pin(pin):
return self._balance
return "PIN码错误"
def __verify_pin(self, pin):
"""验证PIN码(私有方法)"""
return pin == self.__pin
def __add_transaction(self, transaction_type, amount):
"""添加交易记录(私有方法)"""
from datetime import datetime
self.__transaction_history.append({
'type': transaction_type,
'amount': amount,
'timestamp': datetime.now(),
'balance': self._balance
})
def get_transaction_history(self, pin):
"""获取交易历史"""
if self.__verify_pin(pin):
return self.__transaction_history.copy()
return "PIN码错误"
def change_pin(self, old_pin, new_pin):
"""修改PIN码"""
if self.__verify_pin(old_pin):
self.__pin = new_pin
return "PIN码修改成功"
return "原PIN码错误"
print("\n=== 属性访问控制 ===")
# 创建银行账户
account = BankAccount("123456789", 1000)
# 正常操作
print(account.deposit(500))
print(account.withdraw(200, "1234"))
print(f"余额: {account.get_balance('1234')}")
# 访问公开属性
print(f"账户号: {account.account_number}")
# 访问受保护属性(可以访问,但不建议)
print(f"受保护的余额: {account._balance}")
# 尝试访问私有属性(会报错或访问不到)
try:
print(account.__pin) # AttributeError
except AttributeError as e:
print(f"无法访问私有属性: {e}")
# 通过名称改写访问私有属性(不推荐)
print(f"通过名称改写访问PIN: {account._BankAccount__pin}")
# 查看所有属性
print(f"账户属性: {[attr for attr in dir(account) if not attr.startswith('__') or attr.startswith('_BankAccount__')]}")
属性装饰器
class Temperature:
"""温度类"""
def __init__(self, celsius=0):
self._celsius = celsius
@property
def celsius(self):
"""摄氏度属性"""
return self._celsius
@celsius.setter
def celsius(self, value):
"""设置摄氏度"""
if value < -273.15:
raise ValueError("温度不能低于绝对零度(-273.15°C)")
self._celsius = value
@property
def fahrenheit(self):
"""华氏度属性(只读)"""
return self._celsius * 9/5 + 32
@property
def kelvin(self):
"""开尔文温度属性(只读)"""
return self._celsius + 273.15
def __str__(self):
return f"{self._celsius}°C ({self.fahrenheit}°F, {self.kelvin}K)"
print("\n=== 属性装饰器 ===")
# 创建温度对象
temp = Temperature(25)
print(f"初始温度: {temp}")
# 修改摄氏度
temp.celsius = 100
print(f"沸点: {temp}")
# 读取不同单位的温度
print(f"摄氏度: {temp.celsius}")
print(f"华氏度: {temp.fahrenheit}")
print(f"开尔文: {temp.kelvin}")
# 尝试设置无效温度
try:
temp.celsius = -300
except ValueError as e:
print(f"温度设置错误: {e}")
# 尝试直接设置华氏度(会报错,因为没有setter)
try:
temp.fahrenheit = 100
except AttributeError as e:
print(f"无法设置华氏度: {e}")
# 使用property的另一种方式
class Circle:
"""圆形类"""
def __init__(self, radius):
self._radius = radius
def get_radius(self):
"""获取半径"""
return self._radius
def set_radius(self, value):
"""设置半径"""
if value <= 0:
raise ValueError("半径必须大于0")
self._radius = value
def get_area(self):
"""获取面积"""
import math
return math.pi * self._radius ** 2
def get_circumference(self):
"""获取周长"""
import math
return 2 * math.pi * self._radius
# 使用property函数创建属性
radius = property(get_radius, set_radius)
area = property(get_area)
circumference = property(get_circumference)
def __str__(self):
return f"圆形(半径={self.radius}, 面积={self.area:.2f}, 周长={self.circumference:.2f})"
print("\n=== property函数方式 ===")
circle = Circle(5)
print(circle)
circle.radius = 10
print(circle)
try:
circle.radius = -5
except ValueError as e:
print(f"半径设置错误: {e}")
运行类和对象基础示例:
python oop_basics.py
7.2 继承和多态
单继承
# 基类(父类)
class Animal:
"""动物基类"""
def __init__(self, name, species):
self.name = name
self.species = species
self.is_alive = True
def eat(self, food):
"""吃东西"""
return f"{self.name}正在吃{food}"
def sleep(self):
"""睡觉"""
return f"{self.name}正在睡觉"
def make_sound(self):
"""发出声音(基类中的通用实现)"""
return f"{self.name}发出了声音"
def __str__(self):
return f"{self.species}: {self.name}"
# 派生类(子类)
class Dog(Animal):
"""狗类"""
def __init__(self, name, breed):
# 调用父类构造方法
super().__init__(name, "狗")
self.breed = breed
self.loyalty = 100
def make_sound(self):
"""重写父类方法"""
return f"{self.name}汪汪叫"
def fetch(self, item):
"""狗特有的方法"""
return f"{self.name}去捡{item}"
def wag_tail(self):
"""摇尾巴"""
return f"{self.name}开心地摇尾巴"
def __str__(self):
return f"{self.breed}狗: {self.name}"
class Cat(Animal):
"""猫类"""
def __init__(self, name, color):
super().__init__(name, "猫")
self.color = color
self.independence = 80
def make_sound(self):
"""重写父类方法"""
return f"{self.name}喵喵叫"
def climb(self, target):
"""猫特有的方法"""
return f"{self.name}爬上了{target}"
def purr(self):
"""呼噜声"""
return f"{self.name}发出呼噜声"
def __str__(self):
return f"{self.color}猫: {self.name}"
class Bird(Animal):
"""鸟类"""
def __init__(self, name, wing_span):
super().__init__(name, "鸟")
self.wing_span = wing_span
self.can_fly = True
def make_sound(self):
"""重写父类方法"""
return f"{self.name}啾啾叫"
def fly(self, destination):
"""鸟特有的方法"""
if self.can_fly:
return f"{self.name}飞向{destination}"
return f"{self.name}不能飞行"
def __str__(self):
return f"鸟: {self.name} (翼展: {self.wing_span}cm)"
print("=== 单继承示例 ===")
# 创建不同的动物
dog = Dog("旺财", "金毛")
cat = Cat("咪咪", "橘色")
bird = Bird("小黄", 25)
# 调用继承的方法
print(dog.eat("狗粮"))
print(cat.sleep())
print(bird.eat("虫子"))
# 调用重写的方法
print(dog.make_sound())
print(cat.make_sound())
print(bird.make_sound())
# 调用特有的方法
print(dog.fetch("球"))
print(cat.climb("树"))
print(bird.fly("南方"))
# 多态演示
animals = [dog, cat, bird]
print("\n=== 多态演示 ===")
for animal in animals:
print(f"{animal}: {animal.make_sound()}")
# 检查继承关系
print("\n=== 继承关系检查 ===")
print(f"dog是Animal的实例: {isinstance(dog, Animal)}")
print(f"dog是Dog的实例: {isinstance(dog, Dog)}")
print(f"dog是Cat的实例: {isinstance(dog, Cat)}")
print(f"Dog是Animal的子类: {issubclass(Dog, Animal)}")
print(f"Animal是Dog的子类: {issubclass(Animal, Dog)}")
# 查看方法解析顺序(MRO)
print(f"Dog的MRO: {Dog.__mro__}")
print(f"Dog的MRO(名称): {[cls.__name__ for cls in Dog.__mro__]}")
多重继承
# 多重继承示例
class Flyable:
"""可飞行的混入类"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.altitude = 0
def take_off(self):
"""起飞"""
self.altitude = 100
return f"起飞,当前高度: {self.altitude}米"
def land(self):
"""降落"""
self.altitude = 0
return f"降落,当前高度: {self.altitude}米"
def fly_to_altitude(self, target_altitude):
"""飞到指定高度"""
self.altitude = target_altitude
return f"飞行到{target_altitude}米高度"
class Swimmable:
"""可游泳的混入类"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.depth = 0
def dive(self, target_depth):
"""潜水"""
self.depth = target_depth
return f"潜水到{target_depth}米深度"
def surface(self):
"""浮出水面"""
self.depth = 0
return f"浮出水面,当前深度: {self.depth}米"
def swim(self, direction):
"""游泳"""
return f"向{direction}游泳"
class Duck(Animal, Flyable, Swimmable):
"""鸭子类(多重继承)"""
def __init__(self, name):
# 使用super()确保所有父类都被正确初始化
super().__init__(name, "鸭子")
def make_sound(self):
"""重写父类方法"""
return f"{self.name}嘎嘎叫"
def quack(self):
"""鸭子特有的叫声"""
return f"{self.name}发出响亮的嘎嘎声"
class Penguin(Animal, Swimmable):
"""企鹅类(不能飞行,但能游泳)"""
def __init__(self, name):
super().__init__(name, "企鹅")
def make_sound(self):
return f"{self.name}发出企鹅叫声"
def slide_on_ice(self):
"""在冰上滑行"""
return f"{self.name}在冰上滑行"
print("\n=== 多重继承示例 ===")
# 创建鸭子和企鹅
duck = Duck("唐老鸭")
penguin = Penguin("波波")
# 鸭子的多种能力
print(duck.make_sound())
print(duck.eat("鱼"))
print(duck.take_off())
print(duck.fly_to_altitude(200))
print(duck.land())
print(duck.dive(5))
print(duck.swim("北方"))
print(duck.surface())
print()
# 企鹅的能力
print(penguin.make_sound())
print(penguin.dive(20))
print(penguin.swim("东方"))
print(penguin.slide_on_ice())
print(penguin.surface())
# 检查多重继承的MRO
print(f"\nDuck的MRO: {[cls.__name__ for cls in Duck.__mro__]}")
print(f"Penguin的MRO: {[cls.__name__ for cls in Penguin.__mro__]}")
# 检查实例关系
print(f"\nduck是Animal的实例: {isinstance(duck, Animal)}")
print(f"duck是Flyable的实例: {isinstance(duck, Flyable)}")
print(f"duck是Swimmable的实例: {isinstance(duck, Swimmable)}")
print(f"penguin是Flyable的实例: {isinstance(penguin, Flyable)}")
抽象基类
from abc import ABC, abstractmethod
# 抽象基类
class Shape(ABC):
"""形状抽象基类"""
def __init__(self, name):
self.name = name
@abstractmethod
def area(self):
"""计算面积(抽象方法)"""
pass
@abstractmethod
def perimeter(self):
"""计算周长(抽象方法)"""
pass
def describe(self):
"""描述形状(具体方法)"""
return f"{self.name}: 面积={self.area():.2f}, 周长={self.perimeter():.2f}"
def __str__(self):
return self.name
class Rectangle(Shape):
"""矩形类"""
def __init__(self, width, height):
super().__init__("矩形")
self.width = width
self.height = height
def area(self):
"""实现抽象方法"""
return self.width * self.height
def perimeter(self):
"""实现抽象方法"""
return 2 * (self.width + self.height)
def __str__(self):
return f"矩形({self.width}x{self.height})"
class Circle(Shape):
"""圆形类"""
def __init__(self, radius):
super().__init__("圆形")
self.radius = radius
def area(self):
"""实现抽象方法"""
import math
return math.pi * self.radius ** 2
def perimeter(self):
"""实现抽象方法"""
import math
return 2 * math.pi * self.radius
def __str__(self):
return f"圆形(半径={self.radius})"
class Triangle(Shape):
"""三角形类"""
def __init__(self, a, b, c):
super().__init__("三角形")
self.a = a
self.b = b
self.c = c
# 验证三角形的有效性
if not (a + b > c and b + c > a and a + c > b):
raise ValueError("无效的三角形边长")
def area(self):
"""使用海伦公式计算面积"""
s = self.perimeter() / 2
import math
return math.sqrt(s * (s - self.a) * (s - self.b) * (s - self.c))
def perimeter(self):
"""实现抽象方法"""
return self.a + self.b + self.c
def __str__(self):
return f"三角形({self.a}, {self.b}, {self.c})"
print("\n=== 抽象基类示例 ===")
# 创建具体形状
rectangle = Rectangle(5, 3)
circle = Circle(4)
triangle = Triangle(3, 4, 5)
shapes = [rectangle, circle, triangle]
# 多态调用
for shape in shapes:
print(shape.describe())
# 尝试实例化抽象类(会报错)
try:
abstract_shape = Shape("抽象形状")
except TypeError as e:
print(f"\n无法实例化抽象类: {e}")
# 形状计算器
class ShapeCalculator:
"""形状计算器"""
@staticmethod
def total_area(shapes):
"""计算总面积"""
return sum(shape.area() for shape in shapes)
@staticmethod
def total_perimeter(shapes):
"""计算总周长"""
return sum(shape.perimeter() for shape in shapes)
@staticmethod
def largest_shape(shapes):
"""找到面积最大的形状"""
return max(shapes, key=lambda shape: shape.area())
@staticmethod
def sort_by_area(shapes):
"""按面积排序"""
return sorted(shapes, key=lambda shape: shape.area())
print("\n=== 形状计算器 ===")
calculator = ShapeCalculator()
print(f"总面积: {calculator.total_area(shapes):.2f}")
print(f"总周长: {calculator.total_perimeter(shapes):.2f}")
print(f"最大形状: {calculator.largest_shape(shapes)}")
print("\n按面积排序:")
for shape in calculator.sort_by_area(shapes):
print(f" {shape}: {shape.area():.2f}")
运行继承和多态示例:
python inheritance_polymorphism.py
7.3 特殊方法(魔术方法)
基本特殊方法
class Vector:
"""二维向量类"""
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
"""字符串表示(用户友好)"""
return f"Vector({self.x}, {self.y})"
def __repr__(self):
"""字符串表示(开发者友好)"""
return f"Vector({self.x!r}, {self.y!r})"
def __eq__(self, other):
"""相等比较"""
if isinstance(other, Vector):
return self.x == other.x and self.y == other.y
return False
def __ne__(self, other):
"""不等比较"""
return not self.__eq__(other)
def __lt__(self, other):
"""小于比较(按长度)"""
if isinstance(other, Vector):
return self.magnitude() < other.magnitude()
return NotImplemented
def __le__(self, other):
"""小于等于比较"""
return self < other or self == other
def __gt__(self, other):
"""大于比较"""
if isinstance(other, Vector):
return self.magnitude() > other.magnitude()
return NotImplemented
def __ge__(self, other):
"""大于等于比较"""
return self > other or self == other
def __add__(self, other):
"""向量加法"""
if isinstance(other, Vector):
return Vector(self.x + other.x, self.y + other.y)
return NotImplemented
def __sub__(self, other):
"""向量减法"""
if isinstance(other, Vector):
return Vector(self.x - other.x, self.y - other.y)
return NotImplemented
def __mul__(self, scalar):
"""标量乘法"""
if isinstance(scalar, (int, float)):
return Vector(self.x * scalar, self.y * scalar)
return NotImplemented
def __rmul__(self, scalar):
"""右乘法(支持 scalar * vector)"""
return self.__mul__(scalar)
def __truediv__(self, scalar):
"""标量除法"""
if isinstance(scalar, (int, float)) and scalar != 0:
return Vector(self.x / scalar, self.y / scalar)
return NotImplemented
def __neg__(self):
"""负号"""
return Vector(-self.x, -self.y)
def __abs__(self):
"""绝对值(向量长度)"""
return self.magnitude()
def __bool__(self):
"""布尔值(零向量为False)"""
return self.x != 0 or self.y != 0
def __hash__(self):
"""哈希值(使对象可以作为字典键)"""
return hash((self.x, self.y))
def magnitude(self):
"""计算向量长度"""
import math
return math.sqrt(self.x ** 2 + self.y ** 2)
def dot(self, other):
"""点积"""
if isinstance(other, Vector):
return self.x * other.x + self.y * other.y
raise TypeError("点积需要另一个向量")
def normalize(self):
"""归一化向量"""
mag = self.magnitude()
if mag == 0:
raise ValueError("零向量无法归一化")
return Vector(self.x / mag, self.y / mag)
print("=== 特殊方法示例 ===")
# 创建向量
v1 = Vector(3, 4)
v2 = Vector(1, 2)
v3 = Vector(3, 4)
# 字符串表示
print(f"v1: {v1}")
print(f"v1 repr: {repr(v1)}")
# 比较操作
print(f"v1 == v3: {v1 == v3}")
print(f"v1 == v2: {v1 == v2}")
print(f"v1 > v2: {v1 > v2}")
print(f"v1 < v2: {v1 < v2}")
# 算术操作
print(f"v1 + v2: {v1 + v2}")
print(f"v1 - v2: {v1 - v2}")
print(f"v1 * 2: {v1 * 2}")
print(f"3 * v2: {3 * v2}")
print(f"v1 / 2: {v1 / 2}")
print(f"-v1: {-v1}")
# 其他操作
print(f"abs(v1): {abs(v1)}")
print(f"bool(v1): {bool(v1)}")
print(f"bool(Vector(0, 0)): {bool(Vector(0, 0))}")
# 向量运算
print(f"v1 · v2: {v1.dot(v2)}")
print(f"v1 归一化: {v1.normalize()}")
# 作为字典键
vector_dict = {v1: "向量1", v2: "向量2"}
print(f"字典: {vector_dict}")
print(f"v3在字典中: {v3 in vector_dict}")
容器类型特殊方法
class Matrix:
"""矩阵类"""
def __init__(self, data):
"""初始化矩阵"""
if not data or not data[0]:
raise ValueError("矩阵不能为空")
# 检查所有行的长度是否相同
row_length = len(data[0])
if not all(len(row) == row_length for row in data):
raise ValueError("所有行必须有相同的长度")
self.data = [list(row) for row in data] # 深拷贝
self.rows = len(data)
self.cols = len(data[0])
def __str__(self):
"""字符串表示"""
return '\n'.join([' '.join(f'{cell:6.2f}' for cell in row) for row in self.data])
def __repr__(self):
return f"Matrix({self.data!r})"
def __getitem__(self, key):
"""获取元素或行"""
if isinstance(key, tuple):
row, col = key
return self.data[row][col]
else:
return self.data[key]
def __setitem__(self, key, value):
"""设置元素或行"""
if isinstance(key, tuple):
row, col = key
self.data[row][col] = value
else:
if len(value) != self.cols:
raise ValueError(f"行长度必须为{self.cols}")
self.data[key] = list(value)
def __len__(self):
"""返回行数"""
return self.rows
def __iter__(self):
"""迭代行"""
return iter(self.data)
def __contains__(self, item):
"""检查是否包含某个值"""
for row in self.data:
if item in row:
return True
return False
def __add__(self, other):
"""矩阵加法"""
if not isinstance(other, Matrix):
return NotImplemented
if self.rows != other.rows or self.cols != other.cols:
raise ValueError("矩阵维度必须相同")
result = []
for i in range(self.rows):
row = []
for j in range(self.cols):
row.append(self.data[i][j] + other.data[i][j])
result.append(row)
return Matrix(result)
def __mul__(self, other):
"""矩阵乘法或标量乘法"""
if isinstance(other, (int, float)):
# 标量乘法
result = []
for i in range(self.rows):
row = [cell * other for cell in self.data[i]]
result.append(row)
return Matrix(result)
elif isinstance(other, Matrix):
# 矩阵乘法
if self.cols != other.rows:
raise ValueError(f"无法相乘:{self.rows}x{self.cols} 和 {other.rows}x{other.cols}")
result = []
for i in range(self.rows):
row = []
for j in range(other.cols):
cell = sum(self.data[i][k] * other.data[k][j] for k in range(self.cols))
row.append(cell)
result.append(row)
return Matrix(result)
return NotImplemented
def __eq__(self, other):
"""相等比较"""
if not isinstance(other, Matrix):
return False
return self.data == other.data
def transpose(self):
"""转置矩阵"""
result = []
for j in range(self.cols):
row = [self.data[i][j] for i in range(self.rows)]
result.append(row)
return Matrix(result)
def shape(self):
"""返回矩阵形状"""
return (self.rows, self.cols)
print("\n=== 容器类型特殊方法 ===")
# 创建矩阵
m1 = Matrix([[1, 2, 3], [4, 5, 6]])
m2 = Matrix([[7, 8, 9], [10, 11, 12]])
m3 = Matrix([[1, 2], [3, 4], [5, 6]])
print("矩阵 m1:")
print(m1)
print(f"形状: {m1.shape()}")
# 索引访问
print(f"\nm1[0]: {m1[0]}")
print(f"m1[1, 2]: {m1[1, 2]}")
# 修改元素
m1[0, 0] = 100
print(f"修改后 m1[0, 0]: {m1[0, 0]}")
# 长度和迭代
print(f"\nm1 长度: {len(m1)}")
print("迭代 m1:")
for i, row in enumerate(m1):
print(f" 行 {i}: {row}")
# 包含检查
print(f"\n5 在 m1 中: {5 in m1}")
print(f"100 在 m1 中: {100 in m1}")
# 矩阵运算
print("\n矩阵加法 m1 + m2:")
print(m1 + m2)
print("\n标量乘法 m1 * 2:")
print(m1 * 2)
print("\n矩阵乘法 m1 * m3:")
print(m1 * m3)
print("\nm1 转置:")
print(m1.transpose())
上下文管理器
class FileManager:
"""文件管理器(上下文管理器)"""
def __init__(self, filename, mode='r'):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
"""进入上下文"""
print(f"打开文件: {self.filename}")
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_value, traceback):
"""退出上下文"""
if self.file:
print(f"关闭文件: {self.filename}")
self.file.close()
if exc_type is not None:
print(f"处理异常: {exc_type.__name__}: {exc_value}")
return False # 不抑制异常
return True
class Timer:
"""计时器上下文管理器"""
def __init__(self, name="操作"):
self.name = name
self.start_time = None
def __enter__(self):
import time
self.start_time = time.time()
print(f"开始{self.name}...")
return self
def __exit__(self, exc_type, exc_value, traceback):
import time
end_time = time.time()
duration = end_time - self.start_time
print(f"{self.name}完成,耗时: {duration:.4f}秒")
return False
class DatabaseConnection:
"""数据库连接上下文管理器"""
def __init__(self, connection_string):
self.connection_string = connection_string
self.connection = None
self.transaction = None
def __enter__(self):
print(f"连接数据库: {self.connection_string}")
# 模拟数据库连接
self.connection = f"Connection to {self.connection_string}"
print("开始事务")
self.transaction = "Transaction started"
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type is None:
print("提交事务")
else:
print(f"回滚事务,原因: {exc_value}")
print("关闭数据库连接")
self.connection = None
self.transaction = None
return False # 不抑制异常
def execute(self, query):
"""执行查询"""
if not self.connection:
raise RuntimeError("数据库未连接")
print(f"执行查询: {query}")
return f"Result of {query}"
print("\n=== 上下文管理器示例 ===")
# 文件管理器示例
print("1. 文件管理器:")
try:
with FileManager("test.txt", "w") as f:
f.write("Hello, World!")
f.write("\nThis is a test file.")
except FileNotFoundError as e:
print(f"文件操作失败: {e}")
# 计时器示例
print("\n2. 计时器:")
with Timer("数据处理"):
import time
time.sleep(0.1) # 模拟耗时操作
result = sum(range(1000000))
print(f"计算结果: {result}")
# 数据库连接示例
print("\n3. 数据库连接(正常情况):")
with DatabaseConnection("localhost:5432/mydb") as db:
db.execute("SELECT * FROM users")
db.execute("UPDATE users SET active = 1")
print("\n4. 数据库连接(异常情况):")
try:
with DatabaseConnection("localhost:5432/mydb") as db:
db.execute("SELECT * FROM users")
raise ValueError("模拟数据库错误")
db.execute("UPDATE users SET active = 1") # 不会执行
except ValueError as e:
print(f"捕获异常: {e}")
# 嵌套上下文管理器
print("\n5. 嵌套上下文管理器:")
with Timer("数据库操作"):
with DatabaseConnection("localhost:5432/mydb") as db:
db.execute("SELECT COUNT(*) FROM users")
with Timer("复杂查询"):
time.sleep(0.05) # 模拟复杂查询
db.execute("SELECT * FROM users JOIN orders ON users.id = orders.user_id")
运行特殊方法示例:
python special_methods.py
本章小结
本章我们深入学习了Python的面向对象编程:
- 类和对象基础:类定义、实例化、属性访问控制、属性装饰器
- 继承和多态:单继承、多重继承、方法重写、抽象基类
- 特殊方法:运算符重载、容器协议、上下文管理器
下一章预告
下一章我们将学习《异常处理和调试》,内容包括: - 异常的类型和处理 - 自定义异常 - 调试技巧和工具 - 日志记录 - 单元测试
练习题
基础练习
类设计:
- 设计一个学生管理系统
- 实现一个简单的银行账户类
- 创建一个图书馆管理系统
继承实践:
- 设计一个动物园管理系统
- 实现不同类型的员工类
- 创建一个游戏角色系统
进阶练习
特殊方法:
- 实现一个自定义的列表类
- 创建一个复数类
- 设计一个自定义的字典类
设计模式:
- 实现单例模式
- 创建工厂模式
- 设计观察者模式
提示:面向对象编程是Python的核心特性,理解类、继承、多态等概念对于编写高质量的Python代码至关重要。多练习不同的设计模式和应用场景。