无需装饰器,Python能否实现中缀函数组合?
无需装饰器/类包裹,实现Python通用中缀函数组合
当然可以。通过全局修改函数类的__matmul__方法,就能让所有自定义函数(包括lambda和def定义的)直接用@做中缀组合,完全不用给单个函数套装饰器、包装类或者重赋值。
实现代码
把这段代码放进你的<magic>位置就行:
import types def compose(f, g): # f@g 等价于 f∘g:先执行g,把结果传给f def composed(x): return f(g(x)) return composed # 给所有函数类型添加@运算符支持 types.FunctionType.__matmul__ = compose
验证示例
直接用你提供的测试代码就能跑通:
f = lambda x: x g = lambda y: y def h(a): return a # <magic> 就是上面的代码 z = f @ g @ h assert z(1) == 1 # 完全符合预期
核心细节
- 运算顺序:Python中
@是右结合运算符,因此f@g@h会被解析为f@(g@h),最终效果等价于lambda x: f(g(h(x))),符合标准的函数组合逻辑。 - 影响范围:该修改仅作用于自定义函数(
types.FunctionType的实例),像print这类内置函数不受影响——它们属于builtin_function_or_method类型,不在修改范围内。 - 自定义组合逻辑:如果需要反向组合(即
f@g等价于先执行f再执行g),只需调整compose函数的返回逻辑,比如改成return lambda x: g(f(x))。
踩坑提醒
- 这种全局修改内置类的操作叫“猴子补丁”(monkey patching),小场景用起来便捷,但大型项目中可能引发意外副作用,建议仅在可控环境下使用。
- 该方案基于CPython的类型结构实现,更换PyPy等其他Python运行时可能需要微调类型引用方式,但核心思路通用。
内容的提问来源于stack exchange,提问作者Brendan Langfield
相关产品推荐
相关产品推荐

