Python 3.12 新特性

继续感受新特性系列,这次看看于 2023 年 10 月 2 日发布的 Python 3.12 给我们带来了什么新特性。Python 3.14 预计在今年 10 月份推出,一定要对每年一个正式版的新东西有所了解。依旧是由官方的 What's New In Python 3.12 阅读进行展开。

Python 3.12 从编程上的观感变化不大,主要是移除了 distutils, 增加了 f-stringstype 提示,其他对诸如迭代推导等的字节码优化,对性能的提示是不具有直接感受的。

Python 3.12 移除了 distutils(Distribution Utilities)

distutils 是一个 Python 内建的构建,打包和分布 Python 模块/包的工具集,其实对于多数应用开发人员对此也是感的。能与此能顺利建立关联的就是有些 Python 项目中的那个 setup.py 文件,那也是史前的产物。随着 Python 的快速流行,Python 的包管与构建工具也多了起来, 像 Poetry, PDMuv, 尤其是 uv(Rust 编写的) 的闪电速度及全能表现有望成为 Python 界的 Maven。 阅读全文 >>

Python 3.11 关键新特性之其他

前面整一篇只讲了 Python 3.11 的新语法特性,异常组与 except*, 这篇说其他的。

可为异常添加备注

在 BaseException 上新加了一个实例方法 add_note(self, note),在捕获到异常后可进一步润色而无需创建一个新的异常再次抛出。

内置 tomllib 支持 TOML 配置文件

TOML 是 Tom's Obvious Minimal Language, 像 INI 文件,但表述性更强,支持丰富的数据类型。现代新型的 Python 项目依赖管理构建工具都使用了 pyproject.toml 文件,如 Poetry, uv, 以及 PDM。pyproject.toml 在 Python  3.6 就引入了,见 PEF 518,但似乎一直被顽固的 Python -m venv 忽略。

从 Python 3.11 开始新加了对 TOML 配置文件的编程接口,像使用 JSON 和 Pickle 一样的 load() 和 loads() 反序列方法,没有序列化方法 阅读全文 >>

Python 3.11 关键新特性之异常组与 except*

还是在三年前记录的 Python 3.10 关键新特性,一晃 Python 3.13 都出来了。Python 遵循着主版本每 12 个一更新,并提供 5 年支持的节奏。所以自 Python 3.10 于 2021 年 10 月发布以来,又有了 3.11, 3.12, 3.13,还得紧紧跟一跟,踏实的了解每个版本新特性,总由着 AI 帮忙恐难得到自己想要的最优代码。学习必要实践,不然在 Google 或是 ChatGPT 中一问 "Python 3.11 key new features", 到的结果无疑是漂亮的,但只粗略一读,并无半点体会。

学习 Python 3.11 新特性的入口是官方的 What's New In Python 3.11. 同时结合 Google 的相关资料,拣些确实对自己有大益处的学。

官方说的 Python 3.11 比 Python 3.10 要快个  10-60% 估计不是我们升级 Python 的主要动力,一般来说语言或组件能升级的话尽量跟着形势跑,不然越是滞后便越难升级,最终只能原地等死。 阅读全文 >>

尝试 FastAPI WebSocket 写简单的聊天应用

听说 WebSocket 那么一个东西已经很久很久了,但始终未曾尝试,大概对它的了解就是它可以让服务与客户端之间保持一个通道,并实现 Server Push 的功能,这样客户端就无需使用长连接或轮询来与服务端交互,更重要是 WebSocket 能复用 Web 的 80 或 443 端口号,通常是防火墙友好的端口。最近在为 WebSocket 配置 Nginx 反射代理时意识到要加上 Upgrade, Connection 头,加之各种流行的 Web 框架都提供了 WebSocket 的支持,所以又不得不对它重视起来。

下面以 Python 的 FastAPI 框架为例,实现一个简单的聊天站点,主要是参考自 FastAPI 的 WebSockets 官方样例。 当然如果从一开始就询问 ChatGPT: Create a simple chat web app with Python FastAPI framework + WebSocket, 肯定能让你获得一个不错的实现。但本人仍然希望能自我深度思考,而不是让 AI 帮我深度思考,而不是深度思考如何向 ChatGPT 问问题。记得多年前看过一位台湾历史老师讲《史记》, 经常说当看到哪一段时,把课本扣过来,然后思考碰到书中的情形之下自己会怎么想,所以觉得学任何东西当如此。 阅读全文 >>

Apache Airflow 分支与条件流程

来到稍微复杂一点的流程,虽说 DAG 不能有循环但分支还是可以有的。比如下面的分支流程

start >> [task1, task2] >> end

在 Airflow UI 中展示出来就是

Airflow 默认下游 Task 的 trigger_ruleall_success,  即要求上游的所有 Task 都必须成功才会执行,否则跟随着失败或跳过,这对于并行处理然后汇集结果的应用是合理的。

本文将要使用到的是分支(BranchPythonOperator), 比如共用一个 DAG, 周中与周末执行不同的分支,或根据条件从不同的数据源采集数据,下流的任务则需在任何一个分支成功即可触发。对上面的流程加上辅助任务,使其表达性更强 阅读全文 >>

Apache Airflow 3.0 使用 Asset-Aware DAG(producer/consumers)

继续玩弄那个小风车,先前买的 《Data Pipelines with Apache Airflow》 一眼没看直接作废,因为是基于 Apache Airflow 2.x 的,3.0 既出立马又买了该书的第二版,倒是基于 Apache Airflow 3.0 的,但写书之时 3.0 尚未正式推出,所以书中内容与实际应用有许多出入。

Apache Airflow 自 2.4 起就支持基于 Asset 事件触发 DAG,那时叫做 Data-aware,从 Apache Airflow 3.0 起更名为 Asset-Aware, 并且在 UI 上也会显示使用到的 Assets。那么 Asset-Aware  解决什么问题呢,它采用了 Producer/Consumer 模式可把依赖的某一共同资源的  DAG 串联起来。比如某一个 Producer DAG 写了文件到 s3://asset-bucket/example.csv, (发布一个事件 ), 然后相当于订阅了该事件所有相关 Consumer DAG 都会得到执行。

Airflow 的 Asset 使用 URI 的格式

  1. s3://asset-bucket/example.csv
  2. file://tmp/data/export.json
  3. postgresql://mydb/schema/mytable
  4. gs://my-bucket/processed/report.parquet

阅读全文 >>

Apache Airflow 任务中使用模板或上下文

本文大概记录一下在 Apache Airflow 的 Task 或 Operator(这两个基本是同一概念) 中如何使用 模板(Template) 和上下文(Context). Airflow 的模板引擎用的  Jinja Template, 它也被 FastAPI 和 Flask 所采纳。首先只有构造 Operator 时的参数或参数指定的文件内容中,或者调用 Operator render_template() 方法才能用模板语法,像 {{ ds }}.  Apache Airflow 有哪些模板变量可用请参考: Templates references / Variables, 本文将会打印出一个 Task 的 context 变量列出所有可用的上下文变量, 不断的深入,最后在源代码找到相关的定义。

通过使用模板或上下文,我们能能够在任务中使用到 Apache Airflow 一些内置的变量值,如 DAG 或任务当前运行时的状态等 。

当我们手动触发一个 DAG 时, 在 Configuration JSON 中输入的参数也能在 context 中找到. 所有的 Operator  继承链可追溯到 AbstractOperator -> Templater, 因此所有的 Operator(Task) 都能通过调用 Templater.render_template() 方法对模板进行渲染,该方法的原型是 阅读全文 >>

Docker Compose 简单配置 Apache Airflow 3.0(PostgreSQL)

Apache Airflow 重新唤起我的注意力是因为 Airflow 3.0 在近日 April 22, 2025 发布了,其二则是我们一直都有计划任务的需求,以下几种方案都太简陋

  1. 用 Windows 的计划任务或 Linux 的 Cron 都不易管理,且有单点故障问题
  2. 在 Java Spring 项目中使用集群模式的 Quartz 有些麻烦,且对于 AutoScaling 也不怎么友好
  3. AWS 上用 CloudWatch Rule + AWS Lambda 的方案可靠性没有问题,但不适于监控 

因此还有必要再次尝试 Apache Airflow, 它有集中管理的界面,各个部件都是可伸缩的,如 WebServer, Workers 等。特别是刚出的 Apache Airflow 3.0 带来以下主要新特性

  1. 新的服务化架构,各个部件间耦合度降低
  2. 多语言支持,借助了 Task SDK, 可望用 Java, JavaScript, TypeScript 等语言写 DAG
  3. DAG 支持版本控制,可回溯历史
  4. 支持事件驱动,即  DAG 可响应外部事件,如文件到达,消息队列等
  5. 引入了资产驱动调度功能,可根据数据资产的变化 进行触发,可以说是事件驱动的一类
  6. 全新的 React UI 界面

阅读全文 >>

为 FastAPI 的 SwaggerUI 定制 CSS 样式

FastAPI 比起 Flask 而言一个十分便利的功能是它内置对 Swagger UI 文档的支持,然而默认生成的 Swagger UI 也总不尽如人意,于是就有了如何通过引入自己的样式(或样式文件)对默认 Swagger UI 进行定制化的需求。在 ChatGPT 之前,Google 和阅读源代码是齐头并进的选择,自己有了 ChatGPT 之类的 AI, 人们一下就把身段放低了许多,再也不像使用 Google 那样的心态去使用 AI 了。所以呢,第一次支持付了 $8 问问当前号称最厉害的 Grok 3(也算是对 DOGE 的支持吧), 得到答案如下

在网站的 /static 目录下也创建了 custom_swagger.css 文件,然而根本就没有效果,Inspect 浏览器后发现 FastAPI 的 /docs 根本就有加载 /static/custom_swagger.css 文件。 阅读全文 >>

SciPy 最优化之最小化

 SciPy 是一个开源的算法库和数学工具包,可以处理最优化、线性代数、积分、插值、拟合、特殊函数、快速傅里叶变换、信号处理、图像处理、常微分方程求解器等。 它依赖于 NumPy, Pandas 也依赖了 NumPy。本文重点是体验它怎么处理最优化的问题。很多情形下通过 SciPy 的  optimize.minimize 方法寻求目标函数最小值的过程得到最优化的输入与输出。比如寻找二次元函数的根,求解线性/动态规则,金融行业的计算出最优投资组合的资产分配等。为什么 SciPy 没有 maximize 方法呢,因为没有必要,想要找到最大化的值,只要把目标函数的值取反,或者是模或绝对值的最小值。看到 minimize 方法名更让人觉得目标函数会有一个收敛值。

虽然 SciPy 对特定的问题有更直白的函数,如求根有 optimize.root, 线性规则 optimize.linprog(现不建议使用),但各种优化基本都可以回归到 minimize 方法调用。minimize 方法的原型是

除了必须的目标函数和初始值,还有更多参数,像常用的约束(contraints) - 满足某些特定条件的最优化, 线程或非线性约束等; 求解方法(method) - Powell, Newton-CG 等

下面用 optimize.minimize 来求解一些问题 阅读全文 >>