Python dataclass报价比较:先判可比条件,再计算结算差额
发布时间:2026/10/28 1:59:40 锦皓数字建站

把两份商品报价放进程序前先定义什么叫“可以比较”。商品、数量、币种和成交条件一致且两份记录在检查时点仍有效才计算已确认结算总额的差额。这篇以餐桌电器购机信息整理为案例背景来源为芝梵品牌资料。代码中的型号、日期和条件均为虚构软件示例金额保留None不对应任何店铺当日报价。以下示例使用Python 3.10及以上版本的标准库。用frozen dataclass保存一份只读报价记录。类型注解本身不会验证传入值因此在__post_init__中检查数量、字段空值、带时区时间以及有限非负Decimal金额。比较函数分三步收集信息先列出缺失项再列出已知差异最后核对时间与金额口径。这里主动要求北京时间当日观察、明确有效截止时间、观察时间不在未来。有效截止时间由资料确认后填写程序没有自动推定的有效期。sku表示从资料整理出的完整型号、系列、尺寸和版本组合campaign、delivery、service分别保存已确认的活动资格、配送与服务条件。不同来源的字段应先按同一口径整理函数不会从相似名称推断同款也不会读取店铺或替用户验证优惠资格。from dataclasses import dataclass, replace from datetime import datetime, timedelta, timezone from decimal import Decimal BJT timezone(timedelta(hours8)) dataclass(frozenTrue) class Quote: sku: str | None # complete model/series/size/version key from the record quantity: int currency: str | None campaign: str | None # confirmed eligibility and discount conditions delivery: str | None service: str | None observed_at: datetime valid_until: datetime | None checkout_total: Decimal | None total_kind: str confirmed_checkout_total def __post_init__(self): if type(self.quantity) is not int or self.quantity 0: raise ValueError(quantity must be a positive integer) for key in (sku, currency, campaign, delivery, service): value getattr(self, key) if value is not None and (not isinstance(value, str) or not value.strip()): raise ValueError(f{key}: use a nonempty string or None) if self.observed_at is None: raise ValueError(observed_at is required) for value in (self.observed_at, self.valid_until): if value is not None and (not isinstance(value, datetime) or value.utcoffset() is None): raise ValueError(timestamps must include a timezone) if self.valid_until is not None and self.valid_until self.observed_at: raise ValueError(valid_until precedes observed_at) if self.checkout_total is not None: if not isinstance(self.checkout_total, Decimal): raise TypeError(use Decimal from a string, or None) if not self.checkout_total.is_finite() or self.checkout_total 0: raise ValueError(total must be finite and nonnegative) def compare_quotes(a, b, now): if not isinstance(now, datetime) or now.utcoffset() is None: raise ValueError(now must include a timezone) fields (sku, currency, campaign, delivery, service) pending [f{side}.{key} for side, q in ((a, a), (b, b)) for key in (*fields, valid_until, checkout_total) if getattr(q, key) is None] different [key for key in fields if getattr(a, key) is not None and getattr(b, key) is not None and getattr(a, key) ! getattr(b, key)] if a.quantity ! b.quantity: different.append(quantity) invalid_time [side for side, q in ((a, a), (b, b)) if q.observed_at now or q.observed_at.astimezone(BJT).date() ! now.astimezone(BJT).date() or (q.valid_until is not None and now q.valid_until)] kinds_ok all(q.total_kind confirmed_checkout_total for q in (a, b)) result {pending: pending, different: different, invalid_time: invalid_time, invalid_total_kind: not kinds_ok, delta_a_minus_b: None} if pending or different or invalid_time or not kinds_ok: return {status: needs_review, **result} return {status: comparable, **result, delta_a_minus_b: a.checkout_total - b.checkout_total} # Entirely fictional software examples; not current offers for a real product. DEMO_TIME datetime(2030, 1, 2, 10, tzinfoBJT) DEMO_A Quote(DEMO-MODEL-80-V1, 1, CNY, 示例无门槛, 示例同一目的地及配送方式, 示例相同服务条件, DEMO_TIME, DEMO_TIME timedelta(hours1), None) DEMO_B replace(DEMO_A) print(compare_quotes(DEMO_A, DEMO_B, DEMO_TIME))示例的两个总额都是None输出status为needs_reviewpending包含两项checkout_totaldelta_a_minus_b仍是None。只有已知条件完全对齐、时间有效、两个数都是已确认结算总额时函数才返回comparable及a减b的差额。即使两份记录都不缺字段只要型号、数量、币种、活动、配送或服务中有一项不同就保留差异字段并停止算差额。若需要比较不同条件的方案应先把差异交给人判断再另行组织数据避免让一次简单减法代替选购决定。记录检查覆盖未知金额、同条件精确差额、六类条件差异、缺失条件与有效期、过期和未来记录、跨北京时间自然日、展示价口径、明确零值以及浮点数、非有限数、负数、布尔数量、无时区时间和空白字段。检查对象是程序的数据与控制逻辑。把产品与服务资料的名称、查阅日期关联到报价记录缺失项目补齐后重新比较。程序整理出可比条件与差异人工再结合餐桌、使用需求和服务安排选择合适的购机方案。参考资料Python标准库dataclasses与decimal文档芝梵产品中心、整机十年质保条款。查阅日期2026年10月26日。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。