惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
博客园 - 叶小钗
The Cloudflare Blog
D
DataBreaches.Net
J
Java Code Geeks
G
Google Developers Blog
L
LangChain Blog
N
Netflix TechBlog - Medium
Stack Overflow Blog
Stack Overflow Blog
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
小众软件
小众软件
量子位
Apple Machine Learning Research
Apple Machine Learning Research
P
Proofpoint News Feed
博客园_首页
罗磊的独立博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
B
Blog
腾讯CDC

博客园_首页

Linux实操--组管理、权限管理和定时任务 Java + EasyExcel 实现单个接口导出多个Excel Mem0 源码解析系列(二):提示词工程的深度剖析 Openclaw TaskFlow究竟是什么?和普通Skill技能有什么区别 博文阅读密码验证 - 博客园 嘉立创开源:应该是全网MicroPython教程最多的开发板 Hermes Agent 集成实践:从协议到生产 2026年AI编程工具横评:Cursor、Codex、Claude Code、Zed、Windsurf Java程序员必看的RAG入门教程 2026 AI效率神器:Superpowers + Claude Code 保姆级教程 本地大模型部署全攻略:从 0 到 1 玩转 Ollama 【从0到1构建一个ClaudeAgent】内存管理-上下文压缩 .NET 高级开发 | 设计、实现一个事件总线框架 电子小白入门之NE555 3. WorkBuddy:隐藏玩法,一键召唤专家,让 AI 以"专家身份"给你干活 和AI一起搞事情#3:Claude Teammate 游戏开发翻车实录 【OpenClaw】通过 Nanobot 源码学习架构---(7)Memory C# .NET 周刊|2026年3月3期 我在 Debian 11 上把 K8s 单机搭起来了,过程没你想的那么顺(/opt 目录版) 深度学习进阶(七)Data-efficient Image Transformer CLI+Skill搭建浏览器AI自动化框架,告别一切重复枯燥任务 告别Token账单无底洞:OpenClaw本地部署,重塑企业数据主权的唯一解 FastAPI+Vue:文件分片上传+秒传+断点续传,这坑我帮你踩平了! SBTI 爆火后,我做了个程序员版的 CBTI。。已开源 + 附开发过程 多模态检索开始进入工程期:用 Sentence Transformers 搭建可落地的 Multimodal RAG 100多行代码实现一个最简单的Agent(用ReAct) Claude Code 通关手册(八):推荐 5 个 Hooks,代码质量提升 3 倍 老板:“有人截图了!”。安全部门:“收到,马上查暗水印!” - why技术 技术之外,皆是人间 C#/.NET/.NET Core技术前沿周刊 | 第 69 期(2026年4.01-4.12)
21. “|”不只是按位或,90%的人不知道
老陈说编程 · 2026-05-21 · via 博客园_首页

提到 Python 中的|,绝大多数开发者的第一反应都是按位或运算,5 | 3 = 7 是我们初学编程时就烂熟于心的基础。但很少有人知道,| 还能像这样用:

动画视频在《21. “|”不只是按位或,90%的人不知道》

chain = AddOne() | MulTwo() | ToStr()
print(chain.run(5))

Python 里的 | 不只是按位或,90% 的人不知道它还能这么用。一个符号就能把多个函数串成一条流水线,数据从左到右自动流动,代码像管道一样直观。这不是什么黑魔法,而是 Python 一个极其强大但被严重低估的特性 ——运算符重载。今天我们就来彻底解锁 | 运算符的隐藏技能,顺便揭秘 LangChain 中大名鼎鼎的 LCEL 表达式语言的核心原理。

运算符不是语法特权,只是语法糖

很多人觉得 +、-、*、| 这些运算符是 Python 内置的 "特殊语法",只能用于数字、字符串等基本类型。但实际上,Python 中所有运算符都对应着一个特殊的魔法方法。当你写 a | b 时,Python 解释器会自动将其转换为 a.__or__(b)。

这就是整个秘密的核心。只要我们在自己的类中定义了 __or__ 方法,就能完全自定义 | 运算符的行为。不仅是 |,理论上你可以重写所有运算符,让它们实现任何你想要的功能。

运算符 对应方法 默认含义
a & b a.__and__(b) 按位与
a | b a.__or__(b) 按位或
a ^ b a.__xor__(b) 按位异或
~a a.__invert__() 按位取反

用 | 打造你的数据流水线

要实现这样优雅的管道式调用,我们只需要定义几个简单的类。首先是所有任务的基类 Runnable,它规定了所有可运行任务必须实现 run 方法,同时重载了 __or__ 运算符,让两个任务可以用 | 连接成一个链。

class Runnable:
    def run(self, data):
        raise NotImplementedError
    
    def __or__(self, other):
        return Chain(self, other)

接下来是核心的 Chain 类,它本身也继承自 Runnable,这意味着一个任务链本身也是一个可运行的任务。Chain 会把所有步骤按顺序保存起来,执行时依次调用每个步骤的 run 方法,把前一步的输出作为后一步的输入。它也重载了 __or__ 方法,支持给已经存在的链继续追加新的步骤。

class Chain(Runnable):
    def __init__(self, *runnables):
        self.steps = list(runnables)
    
    def run(self, data):
        for step in self.steps:
            data = step.run(data)
        return data
    
    def __or__(self, other):
        return Chain(*self.steps, other)

有了这两个基类,我们就可以像搭积木一样定义各种单一职责的处理步骤了。每个步骤只需要继承 Runnable 并实现自己的 run 方法即可。

class AddOne(Runnable):
    def run(self, data):
        return data + 1
 
class MulTwo(Runnable):
    def run(self, data):
        return data * 2
 
class ToStr(Runnable):
    def run(self, data):
        return f"结果是: {data}"

现在,我们可以用最直观的方式把这些步骤串起来:

chain = AddOne() | MulTwo() | ToStr()
print(chain.run(5))  # 结果是: 12

| 让代码像管道一样直观,数据从左到右流动,一目了然。下次要讲的 LCEL 核心原理就是这个。