11. 进阶学习路径
11.1 Python 编程进阶
11.1.1 高级 Python 特性
装饰器(Decorators)
装饰器是 Python 中一种强大的代码重用机制,允许在不修改原函数代码的情况下扩展函数功能。在电机测试系统中,可以用于日志记录、性能计时、权限验证等。
代码示例:实用装饰器
python
运行
import time
import logging
from functools import wraps
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def log_function_call(func):
"""记录函数调用的装饰器"""
@wraps(func)
def wrapper(*args, **kwargs):
logger.info(f"调用函数: {func.__name__}, 参数: {args}, {kwargs}")
try:
result = func(*args, **kwargs)
logger.info(f"函数 {func.__name__} 执行成功")
return result
except Exception as e:
logger.error(f"函数 {func.__name__} 执行失败: {str(e)}", exc_info=True)
raise # 重新抛出异常,让调用者处理
return wrapper
def measure_execution_time(func):
"""测量函数执行时间的装饰器"""
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
logger.info(f"函数 {func.__name__} 执行时间: {end_time - start_time:.4f} 秒")
return result
return wrapper
def retry_on_failure(max_retries=3, delay_seconds=1):
"""失败时重试的装饰器"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
retries = 0
while retries < max_retries:
try:
return func(*args, **kwargs)
except Exception as e:
retries += 1
if retries < max_retries:
logger.warning(f"函数 {func.__name__} 执行失败,将在 {delay_seconds} 秒后重试({retries}/{max_retries})")
time.sleep(delay_seconds)
else:
logger.error(f"函数 {func.__name__} 达到最大重试次数 {max_retries},执行失败")
raise # 达到最大重试次数,抛出异常
return wrapper
return decorator
# 在电机测试系统中的应用示例
@log_function_call
@measure_execution_time
def process_motor_data(data):
"""处理电机数据"""
# 处理逻辑
pass
@log_function_call
@retry_on_failure(max_retries=5, delay_seconds=2)
def send_data_over_network(data):
"""通过网络发送数据"""
# 发送逻辑
pass
上下文管理器(Context Managers)
上下文管理器用于管理资源,确保资源在使用后被正确释放,如文件、网络连接、数据库连接等。在电机测试系统中,可用于串口连接、文件操作等场景。
代码示例:自定义上下文管理器
python
运行
import serial
import time
class SerialConnection:
"""串口连接上下文管理器"""
def __init__(self, port='COM3', baudrate=115200, timeout=1):
self.port = port
self.baudrate = baudrate
self.timeout = timeout
self.serial = None
def __enter__(self):
"""进入上下文,建立连接"""
try:
self.serial = serial.Serial(
port=self.port,
baudrate=self.baudrate,
timeout=self.timeout
)
print(f"成功打开串口: {self.port}")
return self.serial
except Exception as e:
print(f"打开串口失败: {e}")
raise # 传播异常
def __exit__(self, exc_type, exc_val, exc_tb):
"""退出上下文,关闭连接"""
if self.serial and self.serial.is_open:
self.serial.close()
print(f"已关闭串口: {self.port}")
# 处理异常
if exc_type:
print(f"串口操作发生异常: {exc_val}")
# 返回False表示异常需要继续传播,True表示异常已处理
return False
# 使用示例
def read_serial_data(port='COM3', baudrate=115200):
with SerialConnection(port, baudrate) as ser:
# 在with块中使用串口
while True:
data = ser.readline().decode('utf-8').strip()
if data:
print(f"收到数据: {data}")
time.sleep(0.1)
# 自定义文件处理上下文管理器
class DataFileHandler:
"""数据文件处理上下文管理器"""
def __init__(self, file_path, mode='r'):
self.file_path = file_path
self.mode = mode
self.file = None
def __enter__(self):
"""打开文件"""
self.file = open(self.file_path, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
"""关闭文件"""
if self.file:
self.file.close()
# 处理异常
if exc_type:
print(f"文件操作错误: {exc_val}")
return False
# 使用示例
with DataFileHandler('motor_data.csv', 'w') as f:
f.write('timestamp,current,encoder\n')
# 写入数据...
生成器与迭代器(Generators and Iterators)
生成器是一种特殊的迭代器,能够高效处理大量数据或无限序列,特别适合处理电机测试系统中的数据流。
代码示例:生成器应用
python
运行
import time
import random
def motor_data_generator(motor_id, duration=None):
"""电机数据生成器,模拟实时数据采集"""
start_time = time.time()
while True:
# 如果指定了持续时间,检查是否超时
if duration and time.time() - start_time > duration:
break
# 生成模拟数据
timestamp = time.time()
current = random.uniform(0.5, 3.5) # 电流值在0.5-3.5A之间
encoder = random.uniform(0, 1000) # 编码器值
# 随机产生异常值
if random.random() < 0.05: # 5%的概率产生异常值
current = random.uniform(4.0, 6.0)
yield {
'motor_id': motor_id,
'timestamp': timestamp,
'current': current,
'encoder': encoder,
'status': 'running' if current < 4.0 else 'error'
}
# 模拟采样间隔
time.sleep(0.1)
def data_processor(data_generator, threshold=4.0):
"""数据处理器,过滤异常值"""
for data in data_generator:
if data['current'] > threshold:
# 处理异常数据
yield {**data, 'is_anomaly': True}
else:
yield {** data, 'is_anomaly': False}
# 使用示例
if __name__ == "__main__":
# 创建电机数据生成器,持续10秒
generator = motor_data_generator(motor_id=1, duration=10)
# 创建数据处理器
processor = data_processor(generator)
# 处理数据
for processed_data in processor:
if processed_data['is_anomaly']:
print(f"异常数据: {processed_data}")
else:
# 正常数据可以写入文件或数据库
pass
11.1.2 面向对象编程高级特性
类装饰器与元类
类装饰器和元类是 Python 中用于修改类行为的高级特性,可以实现自动日志记录、属性验证、注册机制等功能。
代码示例:类装饰器与元类
python
运行
def add_logging(cls):
"""为类添加日志功能的装饰器"""
# 遍历类的所有方法
for name, method in cls.__dict__.items():
# 只处理实例方法
if callable(method) and not name.startswith('__'):
# 为方法添加日志功能
def logged_method(method):
def wrapper(self, *args, **kwargs):
print(f"调用 {cls.__name__}.{method.__name__}, 参数: {args}, {kwargs}")
try:
result = method(self, *args, **kwargs)
print(f"{cls.__name__}.{method.__name__} 执行成功")
return result
except Exception as e:
print(f"{cls.__name__}.{method.__name__} 执行失败: {e}")
raise
return wrapper
setattr(cls, name, logged_method(method))
return cls
# 使用类装饰器
@add_logging
class MotorController:
"""电机控制器类"""
def __init__(self, motor_id):
self.motor_id = motor_id
self.current = 0.0
self.running = False
def start(self):
self.running = True
print(f"电机 {self.motor_id} 已启动")
def stop(self):
self.running = False
print(f"电机 {self.motor_id} 已停止")
def set_current(self, current):
if current < 0:
raise ValueError("电流不能为负值")
self.current = current
return self.current
# 元类示例
class ValidationMeta(type):
"""用于属性验证的元类"""
def __new__(cls, name, bases, namespace):
# 遍历类属性
for attr_name, attr_value in namespace.items():
# 如果是属性且有验证器
if isinstance(attr_value, property) and hasattr(attr_value, 'validator'):
# 包装属性的getter方法,添加验证
def make_validated_property(prop):
def getter(self):
return prop.fget(self)
def setter(self, value):
# 调用验证器
if prop.validator(value):
prop.fset(self, value)
else:
raise ValueError(f"属性 {attr_name} 的值 {value} 无效")
return property(getter, setter)
# 替换原始属性
namespace[attr_name] = make_validated_property(attr_value)
return super().__new__(cls, name, bases, namespace)
# 使用元类
class MotorData(metaclass=ValidationMeta):
"""电机数据类,使用元类进行属性验证"""
def __init__(self):
self._current = 0.0
self._temperature = 25.0
@property
def current(self):
return self._current
@current.setter
def current(self, value):
self._current = value
# 添加验证器:电流必须在0-10A之间
current.validator = lambda x: 0 <= x <= 10
@property
def temperature(self):
return self._temperature
@temperature.setter
def temperature(self, value):
self._temperature = value
# 添加验证器:温度必须在-40-100摄氏度之间
temperature.validator = lambda x: -40 <= x <= 100
# 使用示例
if __name__ == "__main__":
# 测试类装饰器
motor = MotorController(1)
motor.start()
motor.set_current(2.5)
motor.stop()
# 测试元类验证
data = MotorData()
data.current = 5.0 # 有效
print(f"电流: {data.current}")
try:
data.current = 11.0 # 无效值,会触发验证错误
except ValueError as e:
print(f"设置电流失败: {e}")
data.temperature = 30.0 # 有效
print(f"温度: {data.temperature}")
try:
data.temperature = 110.0 # 无效值
except ValueError as e:
print(f"设置温度失败: {e}")
抽象基类(Abstract Base Classes)
抽象基类用于定义接口,确保子类实现特定的方法,提高代码的一致性和可维护性。
代码示例:抽象基类应用
python
运行
from abc import ABC, abstractmethod
import time
class MotorInterface(ABC):
"""电机控制抽象基类,定义接口"""
@abstractmethod
def start(self):
"""启动电机"""
pass
@abstractmethod
def stop(self):
"""停止电机"""
pass
@abstractmethod
def set_speed(self, speed):
"""设置电机速度"""
pass
@abstractmethod
def get_status(self):
"""获取电机状态"""
pass
@abstractmethod
def get_sensor_data(self):
"""获取传感器数据"""
pass
class DC Motor(MotorInterface):
"""直流电机实现类"""
def __init__(self, motor_id):
self.motor_id = motor_id
self.running = False
self.speed = 0
self.current = 0.0
self.temperature = 25.0