您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

python中的功能管道,例如R的magritrr中的%>%

python中的功能管道,例如R的magritrr中的%>%

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

与Sylvain Leroux提到的解决方案相比,主要优点是您不需要为要使用的功能创建中缀对象- 只需标记要使用转换的代码区域即可。其次,由于转换是在编译时而不是在运行时应用的,因此转换后的代码在运行时不会受到开销- 所有工作都是在最初从源代码生成字节代码时完成的。

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

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

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语法,用于将输出一个进程传递到另一个进程。

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 2022/1/1 18:30:48 有605人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶