用 Python 的 csv 模块统计订单金额
【摘要】 用 csv.DictReader 读取订单文件,结合 Decimal 统计金额,并检查无效输入。
CSV 文件经常用于交换表格数据。手动用逗号拆分每一行会误读带引号的字段,例如 "笔记本, 大号"。Python 标准库的 csv 模块可以按 CSV 规则读取字段,Decimal 可以避免用二进制浮点数计算十进制金额时产生的常见舍入误差。
下面的示例读取包含 item、quantity 和 unit_price 三列的文件,并计算每行金额与总额。金额输入应使用点作为小数分隔符。
import csv
import sys
from decimal import Decimal, InvalidOperation
from pathlib import Path
def total_orders(path: Path) -> Decimal:
total = Decimal("0")
with path.open(encoding="utf-8-sig", newline="") as file:
reader = csv.DictReader(file)
required = {"item", "quantity", "unit_price"}
if not reader.fieldnames or not required.issubset(reader.fieldnames):
raise ValueError("缺少 item、quantity 或 unit_price 列")
for row in reader:
try:
quantity = int(row["quantity"])
price = Decimal(row["unit_price"])
if quantity < 0 or not price.is_finite() or price < 0:
raise ValueError("数量和单价必须是非负有限数值")
except (ValueError, TypeError, InvalidOperation) as exc:
raise ValueError(f"第 {reader.line_num} 行数据无效") from exc
total += quantity * price
return total
if __name__ == "__main__":
if len(sys.argv) != 2:
raise SystemExit("用法: python orders.py orders.csv")
try:
print(f"总金额: {total_orders(Path(sys.argv[1])):.2f}")
except (OSError, UnicodeError, ValueError, csv.Error) as exc:
raise SystemExit(f"读取失败: {exc}")
示例文件 orders.csv:
item,quantity,unit_price
"笔记本, 大号",2,12.50
签字笔,3,1.20
运行 python orders.py orders.csv,输出为 总金额: 28.60。newline="" 让 CSV 模块控制换行符;utf-8-sig 也能读取带 UTF-8 BOM 的文件。DictReader 按列名取值,因此列顺序可以改变,但列名必须一致。
此示例把数量视为非负整数,只在输出时保留两位小数。如果业务需要逐行四舍五入、退款或其他货币精度,应先明确规则并使用 Decimal.quantize;显示格式不能替代业务舍入规则。示例会读完整个文件并累计金额,但不会保存或修改源文件。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)