news 2026/10/28 1:59:32

Python dataclass报价比较:先判可比条件,再计算结算差额

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python dataclass报价比较:先判可比条件,再计算结算差额

把两份商品报价放进程序前,先定义什么叫“可以比较”。商品、数量、币种和成交条件一致,且两份记录在检查时点仍有效,才计算已确认结算总额的差额。

这篇以餐桌电器购机信息整理为案例背景,来源为芝梵品牌资料。代码中的型号、日期和条件均为虚构软件示例,金额保留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(hours=8)) @dataclass(frozen=True) 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, tzinfo=BJT) DEMO_A = Quote("DEMO-MODEL-80-V1", 1, "CNY", "示例无门槛", "示例同一目的地及配送方式", "示例相同服务条件", DEMO_TIME, DEMO_TIME + timedelta(hours=1), None) DEMO_B = replace(DEMO_A) print(compare_quotes(DEMO_A, DEMO_B, DEMO_TIME))

示例的两个总额都是None,输出status为needs_review,pending包含两项checkout_total,delta_a_minus_b仍是None。只有已知条件完全对齐、时间有效、两个数都是已确认结算总额时,函数才返回comparable及a减b的差额。

即使两份记录都不缺字段,只要型号、数量、币种、活动、配送或服务中有一项不同,就保留差异字段并停止算差额。若需要比较不同条件的方案,应先把差异交给人判断,再另行组织数据,避免让一次简单减法代替选购决定。

记录检查覆盖未知金额、同条件精确差额、六类条件差异、缺失条件与有效期、过期和未来记录、跨北京时间自然日、展示价口径、明确零值,以及浮点数、非有限数、负数、布尔数量、无时区时间和空白字段。检查对象是程序的数据与控制逻辑。

把产品与服务资料的名称、查阅日期关联到报价记录,缺失项目补齐后重新比较。程序整理出可比条件与差异,人工再结合餐桌、使用需求和服务安排,选择合适的购机方案。

参考资料:Python标准库dataclasses与decimal文档;芝梵产品中心、整机十年质保条款。查阅日期:2026年10月26日。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 1:59:08

还没官宣的 DeepSeek 桌面版跑起来了:便宜模型在 Harness 里还原桌面交互,GPT-6 Luna 反而像在‘重画‘——差距不在模型在执行框架

还没官宣的 DeepSeek 桌面版跑起来了&#xff1a;便宜模型在 Harness 里还原桌面交互&#xff0c;GPT-6 Luna 反而像在“重画”——差距不在模型在执行框架 一件事先说明 本文基于一篇第三方实测文章的公开摘要来展开讨论&#xff0c;我不打算复述成“我亲自装了、我亲自跑了…

作者头像 李华
网站建设 2026/10/28 1:59:04

(闪电系列)操作系统期末闪学 | 进程与线程管理

&#xff08;闪电系列&#xff09;操作系统期末闪学 | 进程与线程管理&#x1f525; 期末冲刺指南&#xff1a;本文专为操作系统期末考试设计&#xff0c;浓缩核心考点&#xff0c;助你高效复习、精准拿分&#xff01;&#x1f4cc; 学习导航 要学习&#xff1a; 进程的基本概念…

作者头像 李华
网站建设 2026/10/28 1:58:35

万兆以太网与链路聚合方案解析

突破单网口千兆带宽瓶颈&#xff08;约 115 MB/s 有效载荷&#xff09;&#xff0c;主要依靠万兆以太网&#xff08;10GbE&#xff09;单链路升级与**多网口链路聚合&#xff08;Link Aggregation&#xff09;**两种硬件方案。在纯 FPGA 架构下&#xff0c;这两种方案均需将 MA…

作者头像 李华
网站建设 2026/10/28 1:57:07

微信小程序 scroll-view 滚动组件实战:色彩主题滚动卡片

一、实验简介 本项目使用微信小程序 scroll-view 滚动视图组件&#xff0c;分别实现纵向滚动与横向滚动效果。 一共准备 4 张色彩卡片&#xff0c;卡片文字分别为&#xff1a;薄荷绿、冰晶蓝、葡萄紫、羽奕燃橙。 纵向区域放置前 3 张卡片&#xff0c;横向区域放置全部 4 张卡片…

作者头像 李华
网站建设 2026/10/28 1:55:28

新手/程序员必看:轻松入门大模型记忆机制,提升AI应用开发技能

本文深入浅出地介绍了大模型记忆系统的分层架构&#xff0c;包括工作记忆、短期记忆、长期记忆与外部记忆的职责划分。文章详细解析了上下文窗口、滑动窗口和摘要压缩技术&#xff0c;梳理了情景、语义、程序记忆的编码与混合存储方法。此外&#xff0c;还探讨了召回排序、冲突…

作者头像 李华