26.1CQDataFrame 数据处理
CQDataFrame 基于 pandas 与 numpy,覆盖数据表的创建、筛选、排序、聚合、合并与读写,以及 numpy 数组便捷操作。
cql
从 cqdataframe 导入 数据表, 读取CSV, 范围数组
# 创建数据表
表 = 数据表({"姓名": ["小明", "小红", "小刚"], "年龄": [18, 20, 25]})
print(表.形状()) # (3, 2)
print(表.列们()) # ['姓名', '年龄']
# 查看与统计
print(表.查看头部(2))
print(表.平均值()) # 仅数值列
# 过滤 / 排序
筛选 = 表.过滤(表.列("年龄") > 19) # 年龄大于 19 的行
按年龄 = 表.排序("年龄", 升序=False)
# 读写文件
表.保存CSV("数据.csv")
表2 = 读取CSV("数据.csv")
# numpy 便捷函数
arr = 范围数组(0, 10) # array([0..9])数据表对象
| 分类 | 中文 API |
|---|---|
| 基本信息 | 形状() / 列们() / 行数() / 列数() |
| 浏览与统计 | 查看头部(数量) / 查看尾部(数量) / 描述() / 空值统计() |
| 筛选 | 选择列(*列名) / 过滤(条件) / 按值(列, 值) / 按范围(列, 最小, 最大) / 切片(起, 止) |
| 整理 | 排序(列, 升序) / 去重(列) / 随机抽样(数量) |
| 修改 | 设置列(列名, 值) / 添加行(字典) / 删除列(*列名) / 重命名列(映射) / 填充缺失(值) / 删除缺失() |
| 聚合 | 求和() / 平均值() / 最大值() / 最小值() / 中位数() / 计数() / 标准差() |
| 分组透视 | 分组聚合(列, 聚合) / 透视表(值, 索引, 列, 聚合) |
| 合并拼接 | 合并(其他, 方式, 键) / 连接(其他, 轴) |
| 保存 | 保存CSV(路径) / 保存Excel(路径) / 保存JSON(路径) |
| 转换 | 转列表() / 转字典() / 转数组() / 转字符串() / 迭代行() / 复制() |
系列对象
求和 / 平均值 / 最大值 / 最小值 / 中位数 / 唯一值 / 值计数 / 排序 / 去重 / 映射 / 应用 / 标准化 / 转列表 等,支持 > < >= <= & | ~ 与 Python 运算符构造过滤条件。
numpy 函数
数组、零数组、一数组、全数组、空数组、范围数组、线性空间、随机数组、正态数组、整数数组、点积、转置、重塑、展平、求和、平均值、最大值、最小值。
模块级函数
读取CSV、读取Excel、读取JSON、连接(表们, 轴)、合并(左, 右, 方式, 键)。
提示:
过滤 的条件由 表.列("列名") 与比较运算符构造,返回布尔系列;聚合方法默认只统计数值列,文本列自动忽略;Excel 读写依赖 openpyxl。26.2CQEmail 邮件收发
CQEmail 基于 Python 标准库 smtplib(发送)、imaplib(接收)与 email,无需额外依赖即可收发邮件。
cql
从 cqemail 导入 创建邮件, 发送邮件, 接收邮件, 邮件服务器
# 发送
邮件对象 = 创建邮件(
主题="会议通知",
正文="下午 3 点开会。",
发件人="me@example.com",
收件人=["you@example.com"],
)
邮件对象.添加附件("会议纪要.docx")
发送邮件("smtp.example.com", 465, "me@example.com", "邮箱密码", 邮件对象)
# 使用服务器对象(可复用连接)
with 邮件服务器("smtp.example.com", 465, "me@example.com", "密码") as 服务器:
服务器.发送(邮件对象)
# 接收
消息们 = 接收邮件("imap.example.com", 993, 用户名="me@example.com", 密码="密码", 数量=10)
for 消息 in 消息们:
print(消息.主题, 消息.发件人)
print(消息.正文文本)
if 消息.附件们:
消息.保存附件("下载附件.bin")API 一览
| 中文 API | 说明 |
|---|---|
创建邮件(主题, 正文, 正文HTML, 发件人, 收件人, 抄送, 密送) | 构建邮件对象 |
邮件.添加收件人(地址) / 添加抄送 / 添加密送 | 追加收件人 |
邮件.添加附件(路径, 名称) | 添加附件 |
邮件.设置发件人(地址, 显示名) | 设置发件人(可带中文显示名) |
邮件服务器(主机, 端口=465, 用户名, 密码, 使用SSL) | SMTP 服务器(支持 with) |
服务器.发送(邮件对象) / 发送文本(主题, 正文, 收件人) / 关闭() | 发送操作 |
发送邮件(主机, 端口, 用户名, 密码, 邮件对象) | 一站式发送 |
接收邮件(主机, 端口=993, 用户名, 密码, 邮箱="INBOX", 数量) | 接收邮件 |
未读邮件数(主机, 端口, 用户名, 密码) | 未读邮件数量 |
邮件消息.主题 / 发件人 / 日期 / 正文文本 / 正文HTML / 附件们 | 已收邮件信息 |
注意:中文主题与附件名自动以 MIME Header 编码,收发双方均正常显示;发送端口 465 默认 SSL,使用 587 端口时传
使用SSL=假(自动 STARTTLS);邮箱需开启 SMTP/IMAP 授权码。26.3CQSchedule 定时任务
CQSchedule 基于 APScheduler,支持间隔任务、cron 定时与一次性任务,既可命令式注册,也可用 @每 / @在 装饰器声明。
cql
从 cqschedule 导入 调度器, 每, 在, 启动调度器
调度 = 调度器()
# 间隔任务
调度.间隔任务(心跳, 秒=30) # 每 30 秒
调度.间隔任务(备份, 小时=1) # 每小时
# cron 定时
调度.定时任务(打卡, 小时=9, 分钟=30) # 每天 09:30
调度.定时任务(日报, 星期="mon-fri", 小时=18) # 工作日 18:00
# 一次性任务
调度.日期任务(到期提醒, 时间(2026, 12, 31, 23, 59))
调度.启动() # 后台运行,不阻塞主线程
# 链式装饰器写法(全局调度器)
@每(5).秒
def 心跳():
print("心跳")
@在("14:00").每天
def 打卡():
print("打卡")
启动调度器() # 前台运行(脚本末尾阻塞)API 一览
| 中文 API | 说明 |
|---|---|
调度器(时区, 后台, 日志级别) | 调度器(后台默认不阻塞) |
调度.间隔任务(函数, 秒/分钟/小时/天/周) | 间隔任务 |
调度.定时任务(函数, 小时, 分钟, 秒, 星期, 日, 月, 年) | cron 定时 |
调度.日期任务(函数, 运行时间) / 运行一次(函数) | 一次性任务 / 立即执行 |
调度.启动 / 停止 / 暂停 / 恢复 / 清空 | 调度器控制 |
调度.任务们() / 获取任务(编号) / 移除任务(编号) | 任务管理 |
任务.编号 / 名称 / 下次运行时间 / 暂停 / 恢复 / 移除 / 修改 | 任务句柄 |
每(数值).秒/分钟/小时/天/周.执行(函数) | 链式间隔(也可作装饰器) |
在("14:00").每天 / 在("2026-12-31 23:59").一次 | 链式定时 |
获取调度器() / 启动调度器(前台) / 停止调度器() | 全局调度器 |
注意:后台调度器不阻塞主线程,脚本退出前若需完成任务请用
停止(等待=真);启动调度器(前台=真) 会阻塞直到 Ctrl+C;cron 的 星期 支持 "mon-fri"、"1-5"、"mon,wed,fri" 等 APScheduler 表达式。26.4CQTest 单元测试
CQTest 基于 pytest,核心断言不依赖 pytest(基于标准 assert),测试标记与夹具复用 pytest 生态。
cql
从 cqtest 导入 测试, 参数化, 断言等于, 期望异常, 跳过, 运行
@测试
def 测试加法():
断言等于(1 + 1, 2)
@参数化("数值, 期望", [(1, 1), (2, 4), (3, 9)])
def 测试平方(数值, 期望):
断言等于(数值 ** 2, 期望)
@测试
def 测试异常():
with 期望异常(ValueError):
int("abc")
@跳过("待实现")
def 测试待办():
跳过
运行() # 运行当前模块中所有 @测试,打印通过/失败统计断言系列
| 分类 | 中文 API |
|---|---|
| 条件 | 断言(条件) / 断言真 / 断言假 |
| 相等 | 断言等于 / 断言不等于 |
| 包含 | 断言包含 / 断言不包含 |
| 比较 | 断言大于 / 断言大于等于 / 断言小于 / 断言小于等于 |
| 数值 | 断言接近(实际, 期望, 误差) |
| 空与非空 | 断言为空 / 断言非空 |
| 身份与类型 | 断言是 / 断言类型 |
上下文管理器
期望异常(异常类型, 消息) 或 抛出(...),with 期望异常(...) as e: 后可访问 e.异常 取捕获的异常对象。
装饰器与运行器
| 分类 | 中文 API |
|---|---|
| 装饰器 | @测试(标记测试)、@参数化("a, b", [(1,1), (2,4)])、@跳过("原因")、@标记("慢")、@夹具(范围, 自动) |
| 运行器 | 运行(*测试)(默认收集当前模块全部 @测试)、运行单个(函数)、收集(模块)、运行pytest(参数) |
注意:
断言 系列函数基于标准 assert,无需安装 pytest 即可使用;中文函数名不能直接被 pytest 自动发现,请用 @测试 标记后调用 运行();想与 pytest 生态互通时用 运行pytest()。