将模块作为可调用管道加载的包。

modpipe的Python项目详细描述


…图片::https://img.shields.io/pypi/v/modpipe.svg
:目标:https://pypi.python.org/pypi/modpipe
…图片::https://img.shields.io/travis/jbn/modpipe.svg
:目标:https://travis ci.org/jbn/modpipe
…图片::https://coveralls.io/repos/github/jbn/modpipe/badge.svg?branch=master
:目标:https://coveralls.io/github/jbn/modpipe?branch=master


=
=
==modpipe:modules-as-pipelines
=
=
=
-
-
-
这是什么?
----


将模块加载为可调用管道的自定包。


----
安装代码块::bash

pip install modpipe

但是,当前的主分支不支持酸洗。
直到我的'pr<;https://github.com/aliles/funcsigs/pull/33>;``被接受,pypi包才会在spark环境中工作。上面的pip
命令将安装我的分支。

----
这是为什么?
----

认识到这个模式,这个包使得使用
模块作为管道(特别是在etl上下文中)变得更容易。

————
我能看一个例子吗?
----

您可以将转换函数
累加在"inserte_pipeline.py"中。当下列代码运行时,

…代码块:python

import modpipe

离子。满嘴都是。
具体地说,假设您在``instept_pipeline.py``,

代码块::python

def两次(x):
return x*2


def怪异对(x):
return x,-x


代码块::python

def f(x):
返回奇怪的配对(两次(x))

——
那又怎样?
——


如果您做了大量痛苦的etl工作,这可能会让您觉得很有用。
如果你不这样做,你可能会说,"那又怎样?"不幸的是,我认为如果没有一个动态屏幕的开发人员(xxx:todo),这个
就不能很好地交流了。
但是,现在,我将依靠tim peter's wonderful
`pep20<;https://www.python.org/dev/peps/pep-0020/pep20&g t;中的最后一句话:`,

好主意——让我们做更多的事情!

通过将转换代码移动到模块中,您可以腾出笔记本
(和认知空间)用于后续步骤。如果您花一点时间
正确命名模块,则导航起来会比较容易。如果
将转换代码划分为不同的逻辑单元,它就有点
健壮。而且,如果您用断言填充管道模块代码,它会记录您对数据的期望。

每个人都希望用与编写其他代码相同的方式编写etl代码:
使用良好的测试套件仔细编写。但是,实际上,由于各种限制,我们不会这样做。另外,这是非常乏味的代码。
这个包(以及我从中提取的那个包,
`vaquero<;https://github.com/jbn/vaquero>;```u)可以识别竞争的需求和任务的实际情况,并与您合作。




----

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



默认情况下,管道中不输入带下划线前缀的可调用项。
假设这些可调用函数是由
在线性化管道中真正需要的函数使用的**辅助函数。

代码块::python

def_encode_as_binary(x):默认不在管道中!
return bin(x)[2:].rjust(32,'0')

return[廑encode廑u as廑binary(seed)for seed in seeds]

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

如上所述,单元测试etl代码是一件痛苦的事情。而且,由于脏数据
几乎连续违反预期,严重阻碍了进展。
与其依赖于转换函数的单元测试,
更容易编写(在模块上下文中)断言
,这些断言记录您的假设,并通过在重新/导入时大声失败来防止意外的回归


以下(人工)示例确保管道的sqrt函数
正确计算平方根并返回与给定数值类型相同的结果。

代码块::python

def sqrt(x):
返回类型(x)(x**0.5)

assert sqrt(1776)==42,"噢!"#如果代码错误,则会大声失败!


~~~~~~~~~~~~~~~~~~~~~~~~~


但是,在许多上下文中,它们使您很难对代码失败时的行为进行推理。在大多数情况下,
管道是模块中函数的线性组合。
因此,如果第85行的函数在使用时引发异常,您将知道只有上面的函数已经执行。这是一个非常有用的认知设备,特别是当你从你的代码中走了六个月,并且只有当它变成一个问题时才再次访问它。有时,
有必要:1)提前中止管道或2)跳过某些函数。这个包为这两种情况都提供了一个sentinel返回值。代码块::python

from lxml.html import fromstring
from modpipe import skipto,done

如果raw_html.strip():
返回{'doc':fromstring(raw_html)}
否则:
返回done(none)任何内容都不能完成!中止!

def extract_title(d):
对于d['doc']中的title。xpath("//title/text()"):
d['title']=title

如果d['title']中有'error'。lower():
返回skipo(cleanup,d)跳到cleanup!
否则:
返回d

t_headers``和'cleanup``在传递的dict上进行了
转换。为了在通信
变异时减少loc,两者都没有返回值。这种风格有利有弊。
但是,无论如何,``modpipe``通过假设返回``none``的
函数的给定参数应该传递给
管道中的下一个函数来处理它。因此,cleanup接收到"d"。

这就引出了一个问题:如果您不想返回任何内容,如何返回?在
这种情况下,需要返回"result"。例如,

…代码块::来自modpipe import r的pythonesult

def f(s):
tok=s.upper().strip()
如果tok else result(none)或done(none)



~~~~~~~~~~~~~~~~~~~~~~~~~~~~
元组是特殊的
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
管道中下一个函数的rity,modpipe star在调用下一个函数时展开
,否则,它将执行f(res)。

…代码块::python

def(x):
return x,-x即add(x,-x)

def g(x,y):
return x+y,x*y,即h(x+y,x*y)

def h(items):
return sum(items)

这仅适用于元组和元组。(也就是说,如果返回一个列表,它总是将整个列表作为参数传递。)您会注意到调用结构不允许使用关键字参数。我试过解决这个问题,但没有发现任何不具侵入性的东西。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
还有别的吗?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

是。"modpipe"中的管道非常友好。尽管spark团队不建议再使用rdd,但是
spark对于编写etl管道很有用。但是,python对象序列化和反序列化给pyspark本身(即rdd上的"map")的转换链增加了很多开销。如果您将
转换收集到序列化为模块的逻辑单元,它将分摊
酸洗相关的费用。这不是scala的速度,但至少你可以以更高效的方式利用现有的基础设施。



~~~~~
misc
~~~~


我想我是从"pymc3<;https://docs.pymc.io/>;"中得到这个想法的。对于主要的
版本bump,很多例子开始使用模块,我一开始觉得它很烦人。然后我意识到这是多么美好。由于建模和
etl往往是并驾齐驱的(尽管比例是1:99),我开始用同样的方式编写
etl代码。我肯定我不是第一个这么做的人,但我以前没见过。(这可能只是很多人不写就自然而然地做的事情之一。)


我还想指出"倭黑猩猩"https://github.com/python bonobo/bonobo>;`。
它更加成熟和灵活。根据文档,

Bonobo是对一个旧Python2.7工具的年轻重写,该工具在生产过程中每天运行数百万次
转换。虽然它可能还没有完成或完全稳定(请允许我们达到1.0),
基本的东西都在那里。


但是,对于90%的项目来说,vaquero(使用modpipe)更适合我。




=
=
history
=


0.0.1(2018-04-30)
-----

*PYPI上的第一个版本。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java无法在spring boot应用程序中启用本机内存跟踪   jakarta ee在Java Web项目上的多窗口   日期将Java时间戳转换为MySQL时间戳,反之亦然   java如何实现异步任务连接到服务器并解析JSON   java为什么我得到索引越界异常?   我们如何在java中以大写字母和小写字母存储同名文件   jni/java:有效不可变本机对象的线程安全发布/共享   Java将文本写入远程文件   int最小硬币算法   java如何设置/获取我在类Vehicle的主方法中创建的类Car的“ford”实例的名称?   java使用计时器在队列已满时重新调度使用者   java从字符串的末尾提取一个子字符串,直到遇到第一个空格为止?   java在SimpleApplication之外正确初始化物理状态