Planet Python 中文 笔记

Planet Python 中文

Planet Python 网站是一个星球网站,它聚合了来自各种来源的 Python 相关内容,包括博客、新闻网站和其他在线出版物。 该网站为个人提供了一个了解 Python 编程世界最新发展的集中点。网站上的内容包括教程、新闻、项目公告和关于各种 Python 相关主题的讨论。 用户可以访问该网站,以了解 Python 社区、新的发布、会议和使用 Python 编程语言的最佳实践。网站的目的是帮助推广和传播 Python 相关内容,从而促进 Python 社区的增长和发展。

笔记线程

本文介绍了一个专注于教授 pytest 的 JupyterLab 工作坊的创建过程。该工作坊规模小巧,足以容纳在一篇博客文章中,却包含了真实工作坊的所有核心要素。它包括一个清单(manifest)、多个页面、交互式操作、自动检查、测验以及配套工具。该工作坊教授 pytest 的基本循环:编写测试、观察其失败,然后修复代码。这一迭代过程被结构化地分布在工作坊的四个独立页面中。一个关键特性是为工作坊创建一个隔离的 Python 环境,确保 pytest 的安装不会影响学习者的系统。这种方法借鉴了之前一次会议演讲中的内容课程,以提升学习体验。过程始于规划并定义可验证的步骤,从而将工作坊与教程区分开来。工作坊通过 jupyter workshop init 命令生成,该命令设置目录结构并创建清单文件。清单中声明了诸如终端访问、文件写入、代码执行和包安装等能力,并由代码检查器(linters)进行验证。清单中的 environment 字段指定了依赖项(如 pytest),这些依赖项将被安装到一个自包含的虚拟环境中。这避免了手动环境配置,使学习者能够专注于 pytest 本身。清单中的 env 条目还禁用了 Python 字节码缓存,以防止因快速修改文件而引发问题。该工作坊利用 files/orders.py 文件,其中包含一个故意存在缺陷的函数供学习者调试。工作坊中的每个页面均使用 Markdown 和特定的操作块来引导学习者完成诸如打开文件、编写代码和运行命令等任务。检查通过 verify 操作实现,该操作自动验证学习者操作的结果,确保学习进度和效果。此外,包含一个 quiz 操作,促使学习者在运行测试之前预测结果,从而强化对 pytest 行为机制的理解。editor-insert 操作允许直接在新代码(如测试)中添加并查看代码。该工作坊的结构和内容旨在实现交互性和教育性,聚焦于 pytest 的实际应用。
CdXz5zHNQW_hkEwNEOUhk.png
作者正在为一款与两个不同图像生成后端交互的 CLI 工具设计共享契约。目标是让 CLI 能够使用通用的 submit(request) 函数,而由每个后端将其转换为自身的 SDK 调用。最初,作者曾考虑使用抽象基类(ABC)作为共享接口,因为它们能够强制实现抽象方法。然而,ABC 需要继承关系,这为第三方可插拔后端引入了耦合。Protocol 类型协议(typing.Protocol)则更为合适,因为它采用结构类型(structural typing)。一个类只要拥有正确签名的相应方法,即可满足 Protocol,而无需显式继承。这种方法将外部实现者与核心包解耦,使提供者能够独立演进。Protocol 促进了基于组合的设计,其中提供者作为值被传递,而非处于严格的继承层次结构中。虽然 Protocol 非常适合描述插件边界,但当提供者需要共享具体行为或实现逻辑时,ABC 更为适用。ABC 可以定义共享方法,并强制具体子类实现这些抽象方法。同时,也可以将两者结合使用:使用 Protocol 定义公共插件边界,使用内部 ABC 在提供者之间共享行为。作者建议默认使用 Protocol,因其契约更轻量,仅在需要共享具体实现或希望运行时强制抽象方法时才切换至 ABC。对于插件生态系统,“按形状符合”(Protocol)通常优于“按继承符合”(ABC)。选择取决于主要需求是定义形状,还是共享具体行为并强制继承层次结构。
作者开发了 jupyterlab-workshop,这是一个 JupyterLab 扩展,旨在解决使用纯 Jupyter Notebook 开展教育研讨会时的局限性。该扩展将指令与学习者实际执行的任务分离开来。指令以侧边栏面板的形式呈现,每一步都是 JupyterLab 环境中的可操作项。这些操作包括运行终端命令、修改文件、创建 Notebook 以及执行代码。研讨会还可验证学习者的进度,并在允许其继续之前强制完成特定任务。与学习者可能被动观看代码执行的 Notebook 不同,该扩展确保学习者在实时执行操作时积极参与。它克服了 Notebook 仅限于单一语言的约束,通过使学习者能够与更广泛的 JupyterLab 环境和外部工具进行交互来实现这一点。这种分离避免了教学内容与已完成工作的混淆,提供了更清晰的学习路径。侧边栏面板提供导航、进度跟踪以及已执行操作的详细信息。每个可执行的步骤并非模拟;点击操作会在实时终端中执行它,或执行指定的任务。该扩展支持多种操作,包括终端操作、文件管理、Notebook 交互和界面操作。研讨会甚至可以设计为在特定时点排列用户界面以优化学习效果。检查点允许学习者保存进度,并在出错时恢复到已知状态。该扩展包含一个健壮的验证系统,支持通过 Python 代码、Shell 命令或基于文件的谓词进行检查。还可以集成测验,答案将反馈到后续步骤中。清单文件(manifest file)规定任务完成是建议性的还是强制性的。安全性通过信任机制得到解决,学习者在执行前需授予研讨会特定的能力。研讨会本身的结构是一个目录,包含清单文件、用于页面的 Markdown 文件以及任何必要的起始文件。这种纯文本结构便于版本控制。页面使用 MyST Markdown 编写,操作定义在代码块中。该扩展可本地安装,或通过 mybinder.org 和 GitHub Codespaces 等服务使用,使研讨会能够在各种环境中运行,而无需复杂的设置。作者选择未使用其之前的平台 Educates,因为该平台需要 Kubernetes,限制了其对小团队和个人的可访问性。
CdXz5zHNQW_ghHpRchT3T.png
本期《PyCoder's Weekly》涵盖了一系列 Python 主题,从性能优化到测试及新功能。文章指出,集合(sets)和字典(dictionaries)的性能并非总是 O(1),在某些情况下可能达到二次时间复杂度。基于属性的测试(property-based testing)借助 Hypothesis 被推广为边缘情况测试的替代方案。一则赞助广告介绍了 ScrapingBee,用于高效的网络爬虫。Python 3.15 中懒加载导入(lazy imports)的预览版被解读,有望加快应用程序启动速度。Django 筹款工作组(Django Fundraising Working Group)发布志愿者招募。PyPI 关于文件托管错误的事故报告被提及。文章探讨了 Nifty Django 中的新功能,如用于动态过滤的 Q() 对象。特写介绍了 Python 创始人 Guido van Rossum。文章《用 1024 字节编写一个 Python 解释器》展示了代码高尔夫(code golfing)实践。还讨论了通过读取 __dict__ 来优化属性访问的“去优化”(deoptimizing)策略。提供了构建高效 Python 开发环境的建议。对远程 Python 数据分析岗位趋势的分析显示,招聘板数量减少,远程工作机会增加。教程讲解了 Python 计时函数以及如何构建可复用的 Timer 类。详细说明了为 Wagtail 原型设计新的命令行界面(CLI)。介绍了 NumPy 的通用函数(ufuncs)及其内部机制。列出了多个新项目与代码仓库,包括 django-ox 和 Plotext。最后,宣布了即将举行的 Python 活动,如 PyCon Cameroon 以及各类聚会。
CdXz5zHNQW_hpByPwlbht.png
近期,"AI 将导致人类灭绝”的观点获得了越来越多的关注。一些 AI 领域的领导者,如 Dario Amodei,估计此类事件发生的概率相当可观。Amodei 关于控制 AI 发展节奏的帖子在知名人士中引发了广泛讨论。然而,作者并不认同这一前提,尽管他/她同样怀有许多担忧。作者将“末日”定义为并非灭绝,而是诸如僵尸网络等持续性的滋扰,即 AI 系统变得难以控制。作者承认当前的 AI 系统令人烦恼,但可以被关闭,而潜在的先进智能体则可能无法如此。作者更担忧 AI 对大型 AI 实验室之外个体的影响,而非像 AI 控制武器之类的生存性威胁。作者认为,控制 AI 发展节奏的概念存在问题,尤其是目前只有少数美国公司主导这场竞赛。这些公司受益于公共数据和资源,如今却提议建立与其自身绑定的第三方评估体系。作者批评只有这些企业应掌控强大 AI 的观点,特别是考虑到其地缘政治动机。作者主张,开源模型将通过广泛的可及性,内在地对 AI 发展形成制约,其机制类似于核扩散。当前的局面——公众支持 AI 发展,却从少数实验室回购其收益——被视为一种有缺陷的经济与地缘政治模式。尽管开源项目正受到 AI 公司的挤压,但中国实验室在扩散能力、拉平竞争格局方面被视为至关重要。作者指出监管失败,现有法律被无视,数据在未经同意的情况下被使用。AI 服务的涌现型代币经济被比作毒品市场,缺乏透明度。理想情况下,AI 发展应惠及公共领域,法规应强制支持知识蒸馏。最终,作者并未预见 AI 灭绝事件的发生,认为大型实验室将有更多可失去之物。相反,主要担忧是 AI 可能对各行各业造成广泛损害,使其成本上升。这种在软件工程领域已显现的、对创新的“新税”,预计将蔓延至其他领域。
Wrapture 现在将 OpenTelemetry 集成为一流的数据追踪目的地。每次安装都包含的“wrapture.otel”子包,使得能够无缝导出到追踪后端。通过在配置中添加“[otel]”表,用户可以启用追踪、指定服务名称,并调整各个信号设置。该配置允许对应用行为进行详细分析,包括错误和请求细节。OpenTelemetry 环境变量决定追踪数据的发送位置,控制台导出器可立即调试。每个应用事件被转换为一个区间,形成层级轨迹。例如,Flask 请求变成服务器区间,内部调用创建嵌套区间。错误状况,如“KeyError”,通过状态码和异常细节被准确捕捉。该仪器自动捕获参数和其他注释数据作为区间属性,敏感信息如信用卡号被涂黑。这确保错误被完整记录,同时出现在具体操作和父请求区间。通过W3C跟踪上下文传播实现多进程分布式追踪。Wrapture 将跟踪上下文头注入到发出请求中,接收服务的中间件对这些请求进行解析。这使得跟踪能够跨越不同服务,保持一致的跟踪 ID。即使启用了 OpenTelemetry 导出,Wrapture 也会保留其自身铸造的跟踪 ID,确保连续性。指标也从相同的追踪事件中生成,提供汇总的洞察,无需显式更换仪器代码。请求时长和调用时长会自动收集并归因于HTTP方法、路由和状态码等相关信息。这些指标提供了宝贵的性能和错误率信息。在OpenTelemetry中使用包裹的开销与直接使用OpenTelemetry SDK相当。包裹通过直接构建完成的覆盖,绕过SDK部分内部开销,从而优化了跨度处理。这带来了更低的成本,尤其是在引发异常的操作中。Wrapture 设计的核心原则始终一致:正确观察实时调用,用于测试和生产追踪。无论是输入测试带还是追踪后端,底层机制始终相同。OpenTelemetry 导出页面提供了更多关于采样和日志信号集成等高级功能的详细信息。
Flask 商店的 /order 端点响应缓慢,目标是找出瓶颈。传统的秒表方法需要修改代码,会产生未链接的日志行,并且难以处理间歇性缓慢的问题。分析器提供的细节过多,会掩盖请求特定的信息。利用现有配置,初步的跟踪立即揭示了时间的细分。请求耗时 37.3 毫秒,视图耗时 36.3 毫秒,服务耗时 35.9 毫秒,账本耗时 35.1 毫秒,而网关仅耗时 8 微秒。这表明账本是导致缓慢的主要原因。“自时间”的概念区分了本身缓慢的操作和因其子项而缓慢的操作。Wrapture 计算出这一点,显示账本本身就很慢,而服务和视图因为调用账本而变慢。使用 wrapture.instrumentation 和 wrapture.timeline 的测试证实了这一点:OrderService.place 的自时间为 173 微秒,总耗时为 31.0 毫秒,而 Ledger.record 占用了大部分时间。标准分析器无法提供这种详细程度的信息。对于长期监控,Aggregate 收集器会收集大量请求的统计信息,包括总时间、自时间、最小时间和最大时间。将三十个请求发送到服务器的报告证实了 Ledger.record 是自时间的最大贡献者。为了跟踪每个租户的缓慢情况,wrapture.annotate 允许添加自定义数据,如“X-Tenant”,到正在进行的事件中。这使得可以过滤跟踪,以确定哪些租户的请求响应更慢。Counter 收集器提供了一种更经济的选择,它只计算操作而不保留持续时间,适用于测试套件中的基于预算的断言(例如,检测 N+1 查询问题)。下一步是将这些事件馈送到跟踪后端。
本项目实现了一个基于 FastAPI 的服务,利用 Azure Entra ID 进行身份验证,并采用细粒度的基于角色的访问控制(RBAC)。访问策略并非硬编码到各个路由中,而是存储在数据库表中。这使得管理员可以在不修改和重新部署应用程序代码的情况下更改用户权限。系统使用 Azure Entra ID 对用户进行身份验证,并从 JWT 声明中获取其角色。端点键与所需角色的映射存储在 EndpointPermission SQLModel 表中。授权逻辑的核心是一个 require 函数,该函数作为 FastAPI 依赖项使用。此函数从数据库中检索端点所需的角色,并检查已认证用户是否拥有其中任一角色。如果未拥有,则抛出 403 Forbidden 错误。端点键字符串是其在路由定义中唯一硬编码的字符串。关键的是,用于管理这些权限的端点本身也受相同的 RBAC 机制保护,确保只有管理员才能修改访问规则。防护措施防止管理员意外撤销自身对权限管理端点的访问权限,并确保角色分配永远不会为空。文章指出了两个常见的 Azure 配置问题:使用 v1 令牌而非 v2,导致令牌无效错误;以及嵌套组成员资格不会直接反映在用户角色分配中。该项目还提供了关于如何有效测试授权逻辑的指导。测试可以覆盖身份验证和会话依赖项,使用虚拟用户和内存 SQLite 数据库,从而在不依赖外部组件的情况下进行全面测试。通过将策略外部化为数据,该设计使授权具有动态性和可管理性,符合 12 要素应用原则。作者强调需区分代码逻辑与可变更的策略。
本期《PyCoder's Weekly》涵盖了面向 Python 开发者的多个主题。其中包含关于性能剖析以及如何让 Python 应用程序默认具备高性能的讨论,呼应了 Den Odell 的新书《Fast by Default》。另一篇关键文章探讨了从 pandas 迁移到 Polars 的策略,包括在大型语言模型(LLM)辅助下实现完整数据管道的迁移。此外,还发布了关于 PR-AF 的公告,这是一个开源代码审查工具,在 Code-Review-Bench 基准测试中表现优异。多篇文章深入探讨了 Python 的实际用法,例如在魔术方法(dunder methods)中何时使用 NotImplemented,以及如何利用 Pydantic 和 FastAPI 构建插件架构。PyPI.org 发布了一项重要更新:元数据请求不再计入包下载量,从而提高了下载统计数据的准确性。教程部分提供了构建人脸识别工具以及修复常见"NoneType"对象错误的指导。其他教育内容包括 Python 装饰器的入门指南,以及关于如何有效测试异步 Python 的见解。开发者还可以学习如何将 Django 的静态文件和媒体文件存储于 Cloudflare R2 上。一些发人深省的文章,如《Analysis Paralysis Sucks》和《Why OOP Exists》,提供了更广泛的开发视角。本期还预览了 Python 3.15,重点介绍了默认 UTF-8 编码的变更,并附带了相应的测验。此外,本期还收录了 Shedskin 项目(一个 Python 到 C++ 的转译器)以及 Pandas-silent-bugs 项目,后者展示了 pandas 中众多隐蔽错误的实例。最后,列出了 2026 年 9 月 Python 社区即将举行的活动,包括各类聚会(meetups)以及 PyCon Cameroon。
CdXz5zHNQW_IGTZIgus4k.png
本文描述了如何使用"wrapture"工具在不修改源代码的前提下观察和追踪 Python 程序。最初,追踪涉及编辑程序的入口点,这对于继承或共享的代码而言并不理想。一种更灵活的方法是使用独立的配置文件wrapture.toml来指定观察目标以及追踪数据的输出位置。该配置文件定义了观察目标及其关联的方法,以及数据脱敏规则。wrapture.toml 文件允许针对模块中的特定方法名或通配符模式进行匹配。该工具通过python -m wrapture后接程序脚本来运行,在程序执行前应用配置。此方法生成的追踪输出与修改源代码的方法相同,但将观察逻辑外部化。对于长时间运行的应用程序,追踪输出可重定向至文件(如trace.jsonl),采用 JSON Lines 格式。该文件格式捕获详细的事件信息,包括参数、结果、异常和耗时,使其易于通过常用工具(如jq)进行处理。关于保持追踪激活的安全考量包括:使用有界队列以防止阻塞,以及对参数进行摘要处理以避免保留活动对象。当无法直接通过命令行执行时,可使用autowrapt通过环境变量在解释器启动时注入 wrapture。这种引导机制通常旨在用于开发或调试环境,而非生产环境。一旦注入追踪,即可通过wrapture.bootstrap提供的功能动态控制——暂停、恢复或完全回退,而无需重启应用程序。wrapture 的下一步工作是将此追踪能力应用于更复杂的应用单元,例如 Web 应用程序中常见的单元。
Wrapture 绑定最初用于单元测试,也可作为强大的追踪机制。绑定会观察方法调用并触发事件,这些事件随后由“接收器”(sink)处理,而非测试磁带。这使得对运行中的程序进行实时叙述成为可能。本文通过一个 OrderService 示例加以说明,其中包含 Gateway、Ledger 和 Notifier 组件,支持信用卡支付被拒绝的场景。三个绑定被应用于关键方法:OrderService.place、Gateway.charge 和 Ledger.record。一个简单的 Printer 接收器用于显示这些事件。输出展示了详细的调用信息,包括参数、返回值和异常,缩进表示调用嵌套层级。关键的是,敏感数据(如卡号)可在绑定级别使用 wrapture.redact() 捕获策略进行脱敏。当未注册任何接收器时,绑定的开销极小,每次调用约增加半个微秒。为管理大型追踪数据,可在接收器或绑定级别应用过滤。接收器级别的过滤,如 wrapture.Depth(1, wrapture.Printer()),将输出限制为顶层调用,提供简洁的概览。绑定级别的过滤使用 when= 参数,接受一个谓词以防止特定调用构建事件,效率极高。然而,when= 仅跳过指定的事件;嵌套调用仍会被记录。若要抑制整个调用树,可在绑定中添加 tree=True,确保“从此处向下”不再进行追踪。绑定还会跟踪 filtered_calls,使用户能够了解哪些操作已被抑制。此配置使程序能够以实时数据自我描述其行为,仅需极少的代码更改,并支持为各种监控需求定制接收器。