1. 面向对象编程进阶核心概念解析
面向对象编程(OOP)作为现代编程范式的主流选择,其进阶内容往往决定了开发者能否真正驾驭这一思想。很多人在掌握了类与对象的基础后,会遇到理解上的瓶颈——知道语法却写不出优雅的面向对象代码。这就像学会了象棋规则却下不好棋一样令人困扰。
我在实际项目中最深刻的体会是:面向对象的核心不在于语法细节,而在于如何用对象思维建模真实世界。当你能把业务需求自然地映射为对象间的协作时,代码会自己变得清晰。下面分享我在Python面向对象进阶路上的关键认知节点。
1.1 从语法到思想的跨越
初学者常犯的错误是把类当作"函数容器"使用。比如这样写购物车:
python复制class ShoppingCart:
def add_item(self, item):
pass
def remove_item(self, item):
pass
def calculate_total(self):
pass
这本质上还是面向过程的思维。进阶的写法应该考虑对象职责:
python复制class ShoppingCart:
def __init__(self, customer):
self.customer = customer
self.items = []
def add(self, product, quantity):
self.items.append(LineItem(product, quantity))
class LineItem:
def __init__(self, product, quantity):
self.product = product
self.quantity = quantity
def subtotal(self):
return self.product.price * self.quantity
关键认知:类不是函数的集合,而是具有状态和行为的实体建模。每个类应该只做一件事,并且把它做好。
1.2 三大特性的深度理解
封装、继承、多态这三个概念在进阶阶段需要有新的认识:
-
封装:不仅是
private/protected的语法,更重要的是信息隐藏。好的封装就像手机——你不需要知道电路细节,只需使用接口。 -
继承:慎用!优先考虑组合而非继承。我见过太多滥用继承导致的"香蕉猴子丛林问题"(你想要香蕉却得到了拿着香蕉的整个丛林)。
-
多态:Python中的鸭子类型(duck typing)让多态更灵活。不需要显式继承关系,只要对象实现了相应方法即可。
实际案例:处理不同支付方式时:
python复制class PaymentProcessor:
def process(self, payment):
payment.execute() # 只要payment有execute方法即可
class CreditCardPayment:
def execute(self):
print("Processing credit card")
class PayPalPayment:
def execute(self):
print("Processing PayPal")
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Python特有的高级特性
2.1 魔术方法的实战应用
Python的魔术方法(magic methods)是进阶必备技能。以下是几个高频使用的:
python复制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})"
def __eq__(self, other):
return self.x == other.x and self.y == other.y
避坑指南:实现
__eq__时通常也需要实现__hash__,否则对象在作为字典键时会有意外行为。
2.2 属性控制的艺术
从简单的@property到描述符协议:
python复制class Temperature:
def __init__(self, celsius):
self.celsius = celsius
@property
def fahrenheit(self):
return self.celsius * 9/5 + 32
@fahrenheit.setter
def fahrenheit(self, value):
self.celsius = (value - 32) * 5/9
更高级的描述符应用:
python复制class ValidatedAttribute:
def __init__(self, min_value, max_value):
self.min_value = min_value
self.max_value = max_value
self.storage_name = None
def __set_name__(self, owner, name):
self.storage_name = name
def __get__(self, instance, owner):
return instance.__dict__[self.storage_name]
def __set__(self, instance, value):
if not (self.min_value <= value <= self.max_value):
raise ValueError(f"Value must be between {self.min_value} and {self.max_value}")
instance.__dict__[self.storage_name] = value
class Person:
age = ValidatedAttribute(0, 120)
def __init__(self, age):
self.age = age
2.3 类工厂和元编程
动态创建类的技巧在某些场景下非常强大:
python复制def record_factory(cls_name, fields):
"""创建一个简单的数据记录类"""
def __init__(self, *args):
attrs = dict(zip(fields, args))
self.__dict__.update(attrs)
cls = type(cls_name, (), {'__init__': __init__})
return cls
Point = record_factory('Point', ['x', 'y'])
p = Point(10, 20)
3. 设计模式在Python中的实现
3.1 策略模式的实际应用
用策略模式实现不同的折扣策略:
python复制from abc import ABC, abstractmethod
class DiscountStrategy(ABC):
@abstractmethod
def apply_discount(self, price):
pass
class NoDiscount(DiscountStrategy):
def apply_discount(self, price):
return price
class PercentageDiscount(DiscountStrategy):
def __init__(self, percentage):
self.percentage = percentage
def apply_discount(self, price):
return price * (1 - self.percentage / 100)
class Order:
def __init__(self, price, discount_strategy=NoDiscount()):
self.price = price
self.discount_strategy = discount_strategy
def final_price(self):
return self.discount_strategy.apply_discount(self.price)
3.2 观察者模式的Pythonic实现
利用Python的弱引用避免内存泄漏:
python复制import weakref
class Observable:
def __init__(self):
self._observers = weakref.WeakSet()
def add_observer(self, observer):
self._observers.add(observer)
def remove_observer(self, observer):
self._observers.discard(observer)
def notify_observers(self, *args, **kwargs):
for observer in self._observers:
observer.update(self, *args, **kwargs)
class Observer:
def update(self, observable, *args, **kwargs):
print(f"Got update from {observable} with args: {args}, kwargs: {kwargs}")
4. 性能优化与高级技巧
4.1 __slots__的内存优化
对于需要创建大量实例的类:
python复制class Point:
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
实测数据:在创建100万个实例时,使用
__slots__可以减少约40%的内存占用。
4.2 缓存的正确实现方式
使用functools.cached_property:
python复制from functools import cached_property
class DataSet:
def __init__(self, data):
self.data = data
@cached_property
def stats(self):
# 复杂计算
return {"mean": sum(self.data)/len(self.data)}
4.3 避免常见的反模式
-
过度使用继承:特别是多重继承,容易导致"钻石问题"
-
滥用全局状态:类属性作为全局变量使用是常见陷阱
-
忽略对象生命周期:特别是涉及资源管理时
-
过度设计:不是所有代码都需要设计模式
5. 测试与调试技巧
5.1 单元测试的最佳实践
使用unittest.mock进行测试:
python复制from unittest.mock import Mock
def test_order_processing():
payment_processor = Mock()
order = Order(payment_processor)
order.process()
payment_processor.charge.assert_called_once_with(order.total)
5.2 调试复杂对象关系
使用pprint和vars检查对象状态:
python复制from pprint import pprint
def debug_object(obj):
print("Object type:", type(obj).__name__)
print("Attributes:")
pprint(vars(obj))
5.3 性能分析工具
使用cProfile分析面向对象代码:
bash复制python -m cProfile -s cumtime my_script.py
6. 项目结构设计建议
6.1 模块化组织
推荐的项目结构:
code复制my_project/
├── models/ # 领域模型
│ ├── __init__.py
│ ├── product.py
│ └── order.py
├── services/ # 业务逻辑
│ ├── __init__.py
│ └── payment.py
├── utils/ # 工具类
│ ├── __init__.py
│ └── validators.py
└── main.py # 入口文件
6.2 循环导入的解决方案
- 使用局部导入
- 重构代码结构
- 引入第三方模块
7. 常见问题解决方案
7.1 如何选择继承还是组合?
我的经验法则:
- 如果是"is-a"关系,考虑继承
- 如果是"has-a"关系,使用组合
- 当不确定时,优先选择组合
7.2 何时使用抽象基类?
abc模块的使用场景:
python复制from abc import ABC, abstractmethod
class Renderer(ABC):
@abstractmethod
def render(self, shape):
pass
class VectorRenderer(Renderer):
def render(self, shape):
print(f"Drawing {shape} as vector")
class RasterRenderer(Renderer):
def render(self, shape):
print(f"Drawing {shape} as pixels")
7.3 Python中的私有成员
实际约定大于强制:
python复制class MyClass:
def __init__(self):
self._protected = 10 # 约定为protected
self.__private = 20 # 名称修饰(name mangling)
def get_private(self):
return self.__private
8. 现代Python特性应用
8.1 数据类的使用
python复制from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
z: float = 0.0 # 默认值
8.2 类型注解的实践
python复制from typing import List, Optional
class TreeNode:
def __init__(
self,
value: int,
left: Optional['TreeNode'] = None,
right: Optional['TreeNode'] = None
):
self.value = value
self.left = left
self.right = right
def traverse(root: TreeNode) -> List[int]:
result = []
# 遍历逻辑
return result
8.3 模式匹配(Python 3.10+)
python复制def handle_event(event):
match event:
case Click(position=(x, y)):
print(f"Clicked at ({x}, {y})")
case KeyPress(key="enter"):
print("Enter pressed")
case _:
print("Unknown event")
9. 实战案例:电商系统设计
9.1 领域模型设计
python复制class Product:
def __init__(self, sku, name, price):
self.sku = sku
self.name = name
self.price = price
class Inventory:
def __init__(self):
self.products = {}
def add_product(self, product, quantity):
self.products[product.sku] = {
'product': product,
'quantity': quantity
}
class Order:
def __init__(self, order_id, customer):
self.order_id = order_id
self.customer = customer
self.items = []
def add_item(self, product, quantity):
self.items.append({
'product': product,
'quantity': quantity
})
9.2 支付处理流程
python复制class PaymentGateway:
def __init__(self, config):
self.config = config
def charge(self, amount, card_info):
# 实际支付处理逻辑
return {"status": "success", "transaction_id": "12345"}
class PaymentProcessor:
def __init__(self, gateway):
self.gateway = gateway
def process_payment(self, order):
total = sum(item['product'].price * item['quantity']
for item in order.items)
result = self.gateway.charge(total, order.customer.card_info)
if result['status'] == 'success':
return PaymentReceipt(
order.order_id,
result['transaction_id'],
total
)
raise PaymentError("Payment failed")
10. 性能敏感场景的优化
10.1 使用__slots__减少内存
python复制class Customer:
__slots__ = ['id', 'name', 'email']
def __init__(self, id, name, email):
self.id = id
self.name = name
self.email = email
10.2 避免不必要的属性访问
优化前:
python复制class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def length(self):
return (self.x**2 + self.y**2)**0.5
优化后:
python复制class Vector:
__slots__ = ['x', 'y']
def __init__(self, x, y):
self.x = x
self.y = y
def length(self):
x, y = self.x, self.y # 局部变量访问更快
return (x**2 + y**2)**0.5
10.3 使用内置数据结构
python复制from collections import namedtuple
# 替代简单的类
Point = namedtuple('Point', ['x', 'y'])
11. 大型项目维护建议
11.1 接口设计原则
- 明确职责:每个类应该只有一个改变的理由
- 最小惊讶原则:方法的行为应该符合直觉
- 文档化契约:明确前置条件和后置条件
11.2 版本兼容性策略
- 使用抽象基类定义稳定接口
- 新增功能通过新方法实现
- 弃用旧功能而不是立即删除
11.3 依赖管理技巧
- 依赖注入优于硬编码依赖
- 使用ABC定义接口
- 考虑依赖倒置原则
12. 调试复杂对象关系
12.1 对象可视化工具
python复制def print_object(obj, indent=0):
print(' ' * indent + f'{type(obj).__name__}:')
if hasattr(obj, '__dict__'):
for k, v in obj.__dict__.items():
if hasattr(v, '__dict__'):
print(' ' * (indent + 2) + f'{k}:')
print_object(v, indent + 4)
else:
print(' ' * (indent + 2) + f'{k}: {v}')
12.2 对象图分析
使用objgraph库:
python复制import objgraph
objgraph.show_backrefs([some_object], filename='backrefs.png')
13. 测试驱动开发实践
13.1 测试用例设计
python复制import unittest
class TestShoppingCart(unittest.TestCase):
def setUp(self):
self.cart = ShoppingCart()
self.product = Product("123", "Book", 10.0)
def test_add_item(self):
self.cart.add_item(self.product, 2)
self.assertEqual(len(self.cart.items), 1)
self.assertEqual(self.cart.items[0].quantity, 2)
def test_remove_item(self):
self.cart.add_item(self.product, 1)
self.cart.remove_item(self.product)
self.assertEqual(len(self.cart.items), 0)
13.2 模拟对象的使用
python复制from unittest.mock import MagicMock
def test_payment_processing():
mock_gateway = MagicMock()
processor = PaymentProcessor(mock_gateway)
order = Order("123", Customer())
processor.process_payment(order)
mock_gateway.charge.assert_called_once()
14. 设计原则深度解析
14.1 SOLID原则实践
- 单一职责原则:一个类只做一件事
- 开闭原则:对扩展开放,对修改关闭
- 里氏替换原则:子类应该可以替换父类
- 接口隔离原则:客户端不应依赖不需要的接口
- 依赖倒置原则:依赖抽象而非具体实现
14.2 DRY原则的平衡
避免过度抽象:
python复制# 不好的抽象
def process_data(data, processor):
if isinstance(data, list):
return [processor(x) for x in data]
elif isinstance(data, dict):
return {k: processor(v) for k, v in data.items()}
else:
return processor(data)
# 更好的方式
def process_list(items, processor):
return [processor(x) for x in items]
def process_dict(mapping, processor):
return {k: processor(v) for k, v in mapping.items()}
15. 架构设计进阶思考
15.1 分层架构设计
典型的三层架构:
code复制presentation/ # 表示层
application/ # 应用逻辑
domain/ # 领域模型
infrastructure/ # 基础设施
15.2 六边形架构
核心思想:业务逻辑在中心,外部适配器通过端口与内部交互
15.3 事件驱动架构
使用事件进行解耦:
python复制class EventBus:
def __init__(self):
self.subscribers = defaultdict(list)
def subscribe(self, event_type, handler):
self.subscribers[event_type].append(handler)
def publish(self, event):
for handler in self.subscribers[type(event)]:
handler(event)
class OrderPlacedEvent:
def __init__(self, order):
self.order = order
16. 性能优化深度技巧
16.1 方法调用优化
使用__call__替代多个小方法:
python复制class Pipeline:
def __init__(self):
self.steps = []
def add_step(self, func):
self.steps.append(func)
def __call__(self, data):
for step in self.steps:
data = step(data)
return data
16.2 内存视图优化
处理大数据时:
python复制class LargeDataProcessor:
def __init__(self, data):
self.data = memoryview(data)
def process_chunk(self, start, end):
chunk = self.data[start:end]
# 处理chunk
17. 并发编程模式
17.1 线程安全设计
python复制from threading import Lock
class Counter:
def __init__(self):
self._value = 0
self._lock = Lock()
def increment(self):
with self._lock:
self._value += 1
@property
def value(self):
with self._lock:
return self._value
17.2 异步编程模式
python复制import asyncio
class AsyncDataLoader:
def __init__(self, url):
self.url = url
async def load(self):
async with aiohttp.ClientSession() as session:
async with session.get(self.url) as response:
return await response.json()
18. 元编程高级技巧
18.1 动态属性访问
python复制class DynamicAttributes:
def __getattr__(self, name):
if name.startswith('fallback_'):
return f"Fallback value for {name}"
raise AttributeError(name)
18.2 类装饰器应用
python复制def log_creation(cls):
original_init = cls.__init__
def logged_init(self, *args, **kwargs):
print(f"Creating {cls.__name__} with args={args}, kwargs={kwargs}")
original_init(self, *args, **kwargs)
cls.__init__ = logged_init
return cls
@log_creation
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
19. 测试覆盖率提升
19.1 边界条件测试
python复制class TestRangeValidator(unittest.TestCase):
def test_min_value(self):
validator = RangeValidator(0, 100)
self.assertTrue(validator.validate(0))
def test_max_value(self):
validator = RangeValidator(0, 100)
self.assertTrue(validator.validate(100))
def test_below_min(self):
validator = RangeValidator(0, 100)
self.assertFalse(validator.validate(-1))
def test_above_max(self):
validator = RangeValidator(0, 100)
self.assertFalse(validator.validate(101))
19.2 猴子补丁技巧
python复制import datetime
from unittest.mock import patch
def is_weekend():
return datetime.datetime.today().weekday() in [5, 6]
class TestWeekendCheck(unittest.TestCase):
@patch('datetime.datetime')
def test_weekend(self, mock_datetime):
mock_datetime.today.return_value.weekday.return_value = 5
self.assertTrue(is_weekend())
@patch('datetime.datetime')
def test_weekday(self, mock_datetime):
mock_datetime.today.return_value.weekday.return_value = 1
self.assertFalse(is_weekend())
20. 持续集成实践
20.1 自动化测试集成
.github/workflows/python-test.yml示例:
yaml复制name: Python Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: |
python -m pytest --cov=.
20.2 代码质量检查
使用pylint和black:
bash复制pylint my_package/
black --check my_package/
21. 文档化最佳实践
21.1 类型注解与文档
python复制class DataLoader:
"""Load data from various sources.
Args:
source: URI of the data source
cache: Whether to use local caching
"""
def __init__(self, source: str, cache: bool = True):
self.source = source
self.cache = cache
def load(self) -> dict:
"""Load and parse the data.
Returns:
Parsed data as dictionary
Raises:
DataLoadError: If loading fails
"""
...
21.2 示例驱动文档
python复制def split_string(s: str, delimiter: str) -> list[str]:
"""Split a string by delimiter.
Example:
>>> split_string("a,b,c", ",")
['a', 'b', 'c']
>>> split_string("hello world", " ")
['hello', 'world']
"""
return s.split(delimiter)
22. 代码审查要点
22.1 面向对象代码审查清单
- 类是否遵循单一职责原则?
- 继承层次是否过深(>3层)?
- 是否有多余的getter/setter?
- 是否存在"上帝对象"?
- 接口设计是否符合最小惊讶原则?
22.2 常见坏味道识别
- 发散式变化:一个类因为不同原因频繁修改
- 散弹式修改:一个变化需要修改多个类
- 依恋情结:方法过度访问其他类的数据
- 数据类:只有数据没有行为的类
- 拒绝遗赠:子类不想要父类的某些方法
23. 重构技巧实战
23.1 提取方法对象
重构前:
python复制class OrderProcessor:
def process(self, order):
# 验证逻辑
if not order.is_valid():
raise InvalidOrderError()
# 计算逻辑
total = sum(item.price * item.quantity for item in order.items)
if order.customer.has_discount():
total *= 0.9
# 支付逻辑
payment_result = payment_gateway.charge(total)
if not payment_result.success:
raise PaymentFailedError()
# 库存逻辑
for item in order.items:
inventory.decrement(item.product, item.quantity)
重构后:
python复制class OrderProcessor:
def __init__(self, payment_gateway, inventory):
self.payment_gateway = payment_gateway
self.inventory = inventory
def process(self, order):
OrderValidator.validate(order)
total = OrderCalculator.calculate_total(order)
PaymentProcessor(self.payment_gateway).process(total)
InventoryUpdater(self.inventory).update(order)
23.2 引入策略模式
重构前:
python复制class ReportGenerator:
def generate(self, format):
if format == "csv":
self._generate_csv()
elif format == "json":
self._generate_json()
elif format == "xml":
self._generate_xml()
重构后:
python复制class ReportGenerator:
def __init__(self, strategy):
self.strategy = strategy
def generate(self):
return self.strategy.generate()
class CsvStrategy:
def generate(self):
# CSV生成逻辑
pass
class JsonStrategy:
def generate(self):
# JSON生成逻辑
pass
24. 领域驱动设计入门
24.1 实体与值对象
python复制class Product: # 实体
def __init__(self, id, name, price):
self.id = id # 标识符是关键
self.name = name
self.price = price
def change_price(self, new_price):
self.price = new_price
class Money: # 值对象
def __init__(self, amount, currency):
self.amount = amount
self.currency = currency
def __eq__(self, other):
return (self.amount == other.amount and
self.currency == other.currency)
24.2 聚合根设计
python复制class Order: # 聚合根
def __init__(self, id, customer):
self.id = id
self.customer = customer
self._items = []
def add_item(self, product, quantity):
if quantity <= 0:
raise ValueError("Quantity must be positive")
self._items.append(OrderItem(product, quantity))
@property
def items(self):
return list(self._items) # 返回副本
class OrderItem: # 属于Order聚合
def __init__(self, product, quantity):
self.product = product
self.quantity = quantity
25. 现代Python项目实践
25.1 依赖注入容器
python复制class Container:
def __init__(self):
self._services = {}
def register(self, name, creator):
self._services[name] = creator
def resolve(self, name):
creator = self._services.get(name)
if not creator:
raise ValueError(f"Service {name} not registered")
return creator(self)
container = Container()
container.register('db', lambda c: Database())
container.register('user_repo', lambda c: UserRepository(c.resolve('db')))
25.2 配置管理
python复制from dataclasses import dataclass
@dataclass
class DatabaseConfig:
host: str
port: int
user: str
password: str
@dataclass
class AppConfig:
debug: bool
database: DatabaseConfig
timeout: int = 30
26. 性能监控与分析
26.1 方法调用追踪
python复制import time
import functools
def trace_method_calls(cls):
for name, method in cls.__dict__.items():
if callable(method):
setattr(cls, name, traced(method))
return cls
def traced(method):
@functools.wraps(method)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = method(*args, **kwargs)
duration = time.perf_counter() - start
print(f"{method.__name__} took {duration:.6f}s")
return result
return wrapper
@trace_method_calls
class DataProcessor:
def process(self, data):
time.sleep(0.1)
return len(data)
26.2 内存使用分析
python复制import tracemalloc
class MemoryTracker:
def __init__(self):
tracemalloc.start()
def snapshot(self):
return tracemalloc.take_snapshot()
def compare_snapshots(self, snapshot1, snapshot2):
stats = snapshot2.compare_to(snapshot1, 'lineno')
for stat in stats[:10]:
print(stat)
27. 安全编程实践
27.1 输入验证模式
python复制class InputValidator:
@staticmethod
def validate_email(email):
if not isinstance(email, str):
raise TypeError("Email must be string")
if "@" not in email:
raise ValueError("Invalid email format")
return email.lower()
27.2 安全序列化
python复制import json
import pickle
class SafeSerializer:
@staticmethod
def to_json(obj):
return json.dumps(obj, default=lambda o: o.__dict__)
@staticmethod
def from_json(json_str):
return json.loads(json_str)
@staticmethod
def safe_pickle(obj):
"""仅允许安全类型的pickle序列化"""
safe_classes = {'Point', 'Rectangle'}
if obj.__class__.__name__ not in safe_classes:
raise ValueError("Unsafe class for pickling")
return pickle.dumps(obj)
28. 跨语言交互设计
28.1 C扩展接口
python复制// example.c
#include <Python.h>
static PyObject* greet(PyObject* self, PyObject* args) {
const char* name;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
return PyUnicode_FromFormat("Hello, %s!", name);
}
static PyMethodDef methods[] = {
{"greet", greet, METH_VARARGS, "Greet someone"},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT,
"example",
NULL,
-1,
methods
};
PyMODINIT_FUNC PyInit_example(void) {
return PyModule_Create(&module);
}
28.2 使用CFFI
python复制# build.py
from cffi import FFI
ffi = FFI()
ffi.set_source("_example", None)
ffi.cdef("""
int printf(const char *format, ...);
""")
if __name__ == "__main__":
ffi.compile()
# usage.py
from _example import ffi
ffi.C.printf(b"Hello, %s!\n", b"world")
29. 异步编程模式
29.1 异步上下文管理器
python复制import aiohttp
import asyncpg
class DatabaseConnection:
def __init__(self, dsn):
self.dsn = dsn
self.conn = None
async def __aenter__(self):
self.conn = await asyncpg.connect(self.dsn)
return self.conn
async def __aexit__(self, exc_type, exc, tb):
await self.conn.close()
async def fetch_data():
async with DatabaseConnection("postgres://user:pass@localhost/db") as conn:
return await conn.fetch("SELECT * FROM users")
29.2 异步迭代器
python复制class AsyncDataStream:
def __init__(self, urls):
self.urls = urls
def __aiter__(self):
self.index = 0
return self
async def __anext__(self):
if self.index >= len(self.urls):
raise StopAsyncIteration
url = self.urls[self.index]
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
data = await response.json()
self.index += 1
return data
30. 项目脚手架设计
30.1 模板项目结构
code复制my_project/
├── src/
│ ├── package/
│ │ ├── __init__.py
│ │ ├── core.py
│ │ └── utils.py
│ └── scripts/
│ └── cli.py
├── tests/
│ ├── __init__.py
│ ├── test_core.py
│ └── test_utils.py
├── docs/
│ └── api.md
├── pyproject.toml
└── README.md
30.2 动态插件加载
python复制import importlib
import pkgutil
from pathlib import Path
class PluginLoader:
def __init__(self, plugin_dir):
self.plugin_dir = Path(plugin_dir)
self.plugins = {}
def load_plugins(self):
for finder, name, _ in pkgutil.iter_modules([str(self.plugin_dir)]):
module = importlib.import_module(f"{self.plugin_dir.name}.{name}")
if hasattr(module, 'register'):
module.register(self)
def register_plugin(self, name, plugin):
self.plugins[name] = plugin
31. 调试技巧进阶
31.1 交互式调试
python复制import code
import inspect
def debug_interactive(frame=None):
"""在调用处启动交互式调试"""
frame = frame or inspect.currentframe().f_back
namespace = frame.f_globals.copy()
namespace.update(frame.f_locals)
code.interact(local=namespace)
31.2 对象状态检查
python复制def inspect_object(obj, max_depth=3, _depth=0):
if _depth >= max_depth:
return f"{obj!r} (max depth reached)"
if hasattr(obj, '__dict__'):
result = f"{type(obj).__name__}:\n"
for k, v in obj.__dict__.items():
result += f"{' '*(_depth+1)}{k}: {inspect_object(v, max_depth, _depth+1)}\n"
return result
return repr(obj)
