[Python] pipe模块

一. 概述

我们都知道在Linux下执行命令ls | sort -r会将排序后的结果降序输出,它是先获取目录数据,管道符|ls的输出作为后一个命令的输入,最终得到降序排序的结果。

Python和其他大多数语言一样,处理数据的时候通常是将数据作为参数传入。但是有没有像Linux管道符那样优雅的输出呢?有的,这就是pipe模块,但需要注意的是pipe模块并不属于Python的标准库,可用pip pipe进行安装。

二. 使用

pipe的使用方法很简单,只需要给处理数据的函数加上@Pipe注解就OK了。如下,

from pipe import * @Pipe def Filter(lst): return [x for x in lst if x > 3] def GetNums(): return [1, 2, 3, 4, 5] res = GetNums() | Filter() print(res)

输出:

[4, 5]

三. 原理

pipe的实现原理和它的使用方式一样简单(正因为简单,才有这篇笔记(╥﹏╥))。它的核心代码只有几行,实际就是一个装饰器。

class Pipe: def __init__(self, function): self.function = function functools.update_wrapper(self, function) def __ror__(self, other): return self.function(other) def __call__(self, *args, **kwargs): return Pipe(lambda x: self.function(x, *args, **kwargs))

好,既然这么简单。我们第二章中的例子自己实现一次,并添加了一些注释和辅助分析的输出以便分析。

# 装饰器 class Pipe: def __init__(self, function): print(f"__init__调用,实例id为:{id(self)}") self.function = function # # 保留传入函数的元信息,可忽略 # functools.update_wrapper(self, function) def __ror__(self, other): print(f"__ror__被调用,传入的参数是:{other}") return self.function(other) def __call__(self, *args, **kwargs): print("__call__被调用") # 返回的是一个Pipe对象,这样就能够使用重载的“|” # 传入一个lambda表达式,是对self.function的再一次封装,回报存在这个Pipe对象的self.function中 return Pipe(lambda x: self.function(x, *args, **kwargs)) @Pipe def Filter(lst): print("Filter被调用") return [x for x in lst if x > 3] print("----- 分割线 -----") def GetNums(): return [1, 2, 3, 4, 5] res = GetNums() | Filter() print(res)

输出:

__init__调用,实例id为:2398974542568 ----- 分割线 ----- __call__被调用 __init__调用,实例id为:2398974542624 __ror__被调用,传入的参数是:[1, 2, 3, 4, 5] Filter被调用 [4, 5]

从结果可以看到,Filter()的作用过程是这样的:

  1. Pipe装饰器包装函数Filter
  2. Filter()的调用实际上就是调用Pipe对象中的__call__方法;
  3. __call__方法中,用lambda对实际的Filter函数再做一次封装(其实这个lambda可以省去的,可自行验证),并传入该lambda表达式生成一个新的Pipe对象;
  4. 之后是将GetNums()函数的返回值作为操作数,传入到__ror__中;
  5. __ror__方法中,调用self.function(实际的Filter函数)处理处理数据,返回结果。
posted @   小贼的自由  阅读(261)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· Open-Sora 2.0 重磅开源!
历史上的今天:
2020-05-23 闰年判断与日期计算
点击右上角即可分享
微信分享提示