Python 中的功能管道,如来自 R 的 magrittr 的 %>% [英] Functional pipes in python like %>% from R's magrittr

查看:30
本文介绍了Python 中的功能管道,如来自 R 的 magrittr 的 %>%的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 R(感谢 magrittr)中,您现在可以通过 %>%.这意味着,而不是编码:

In R (thanks to magrittr) you can now perform operations with a more functional piping syntax via %>%. This means that instead of coding this:

> as.Date("2014-01-01")
> as.character((sqrt(12)^2)

你也可以这样做:

> "2014-01-01" %>% as.Date 
> 12 %>% sqrt %>% .^2 %>% as.character

对我来说,这更具可读性,并且扩展到数据框以外的用例.python 语言是否支持类似的东西?

To me this is more readable and this extends to use cases beyond the dataframe. Does the python language have support for something similar?

推荐答案

一种可能的方法是使用名为 的模块宏.Macropy 允许您将转换应用于您编写的代码.因此 a |b 可以转化为 b(a).这有许多优点和缺点.

One possible way of doing this is by using a module called macropy. Macropy allows you to apply transformations to the code that you have written. Thus a | b can be transformed to b(a). This has a number of advantages and disadvantages.

与 Sylvain Leroux 提到的解决方案相比,主要优点是您不需要为您有兴趣使用的函数创建中缀对象——只需标记您打算使用转换的代码区域.其次,由于转换是在编译时而不是运行时应用的,所以转换后的代码在运行时没有任何开销——所有工作都是在字节码第一次从源代码中生成时完成的.

In comparison to the solution mentioned by Sylvain Leroux, The main advantage is that you do not need to create infix objects for the functions you are interested in using -- just mark the areas of code that you intend to use the transformation. Secondly, since the transformation is applied at compile time, rather than runtime, the transformed code suffers no overhead during runtime -- all the work is done when the byte code is first produced from the source code.

主要缺点是macropy需要通过某种方式激活才能工作(后面会提到).与更快的运行时间相比,源代码的解析在计算上更加复杂,因此程序将需要更长的时间才能启动.最后,它添加了一种语法风格,这意味着不熟悉宏指令的程序员可能会发现您的代码更难理解.

The main disadvantages are that macropy requires a certain way to be activated for it to work (mentioned later). In contrast to a faster runtime, the parsing of the source code is more computationally complex and so the program will take longer to start. Finally, it adds a syntactic style that means programmers who are not familiar with macropy may find your code harder to understand.

run.py

import macropy.activate 
# Activates macropy, modules using macropy cannot be imported before this statement
# in the program.
import target
# import the module using macropy

target.py

from fpipe import macros, fpipe
from macropy.quick_lambda import macros, f
# The `from module import macros, ...` must be used for macropy to know which 
# macros it should apply to your code.
# Here two macros have been imported `fpipe`, which does what you want
# and `f` which provides a quicker way to write lambdas.

from math import sqrt

# Using the fpipe macro in a single expression.
# The code between the square braces is interpreted as - str(sqrt(12))
print fpipe[12 | sqrt | str] # prints 3.46410161514

# using a decorator
# All code within the function is examined for `x | y` constructs.
x = 1 # global variable
@fpipe
def sum_range_then_square():
    "expected value (1 + 2 + 3)**2 -> 36"
    y = 4 # local variable
    return range(x, y) | sum | f[_**2]
    # `f[_**2]` is macropy syntax for -- `lambda x: x**2`, which would also work here

print sum_range_then_square() # prints 36

# using a with block.
# same as a decorator, but for limited blocks.
with fpipe:
    print range(4) | sum # prints 6
    print 'a b c' | f[_.split()] # prints ['a', 'b', 'c']

最后是完成艰苦工作的模块.我将它称为函数管道的 fpipe,因为它模拟了 shell 语法,用于将输出从一个进程传递到另一个进程.

And finally the module that does the hard work. I've called it fpipe for functional pipe as its emulating shell syntax for passing output from one process to another.

fpipe.py

from macropy.core.macros import *
from macropy.core.quotes import macros, q, ast

macros = Macros()

@macros.decorator
@macros.block
@macros.expr
def fpipe(tree, **kw):

    @Walker
    def pipe_search(tree, stop, **kw):
        """Search code for bitwise or operators and transform `a | b` to `b(a)`."""
        if isinstance(tree, BinOp) and isinstance(tree.op, BitOr):
            operand = tree.left
            function = tree.right
            newtree = q[ast[function](ast[operand])]
            return newtree

    return pipe_search.recurse(tree)

这篇关于Python 中的功能管道,如来自 R 的 magrittr 的 %>%的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆