用 Python 的 csv 模块统计订单金额

举报
yd_251192881 发表于 2026/11/03 16:40:09 2026/11/03
【摘要】 用 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)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。