【问题标题】:How do I perform some operation on the output of a function in Python?如何在 Python 中对函数的输出执行一些操作?
【发布时间】:2025-12-05 10:50:02
【问题描述】:

我试图让函数的输出表现得好像它是我的输入一样。目标是从旧输出中生成新输出。

我有一些看起来像这样的代码:

def func():

    BLOCK OF CODE

func()

函数中没有return语句,括号内也没有参数。 当我键入func() 来调用我的函数时,如上所示,我得到了所需的输出,这是一堆打印的语句。现在我想用那个输出做点什么来得到另一个输出。 我要做的就是有效地将一个函数的输出“管道”到另一个函数的输入中(或者,如果可能的话,甚至根本不用担心创建另一个函数,而是做一些更直接的事情)。我调查了Python 3 writing to a pipe 但这对我没有帮助。我还尝试定义另一个函数,并使用前面的函数作为参数,这也不起作用:

def another_func(func):
    print another_statement

another_func(func)

我也尝试过做一个闭包(这“有点”奏效,因为它至少打印了与 func() 打印的相同的东西,但仍然不是很令人鼓舞):

def func():
    def another_func():
        print another_statement
    BLOCK OF CODE

another_func()

最后,我尝试同时设计一个装饰器和一个嵌套函数来实现这一点,但我的函数中没有参数,这真的让我的代码丢了(根本没有打印任何东西)。

关于如何像操作输入一样操作函数的输出以便可以创建新输出的任何建议?

【问题讨论】:

  • print 不是“函数的输出”,而是对流的副作用。拦截print 的问题在Python 2.x 中变得额外.. 有趣.. print 是一个特殊的内置函数。
  • 看我的回答......它应该工作......即使我认为它可能不建议在实际代码中使用......

标签: python function


【解决方案1】:

可以通过使用装饰器重定向标准输出来实现:

from StringIO import StringIO
import sys

def pipe(f):
    def decorated(*args, **kwargs):
        old,sys.stdout = sys.stdout,StringIO()

        try:
            result = f(*args, **kwargs)
            output = sys.stdout.getvalue()
        finally:
            sys.stdout = old

        return result, output
    return decorated

然后您可以从任何修饰函数中获取 result, output 对,例如:

@pipe
def test(x):
    print x
    return 0

test(3) -> (0, '3\n')

但是,我想不出你想要这样做的充分理由。

(实际上,这不是完全正确的;在为用户 IO 编写单元测试时很方便,例如在软件工程课程中测试学生作业时。我严重怀疑这就是 OP不过,试着去做。)

【讨论】:

  • +1 与我的答案相同...但更漂亮,并且带有非常有效的免责声明“我想不出这样做的充分理由”
  • @JoranBeasley - 更漂亮,但你的功能更强大(因为我没有在引发异常时修复标准输出)。被盗并修复,谢谢:)
【解决方案2】:

从函数返回所需的值 - 不是在控制台上打印值,而是将它们作为字符串、数字、列表或任何其他有意义的类型返回。否则,如果没有输出开始,您如何期望将函数的输出作为输入“连接”到另一个函数?

当然,在控制台上打印不算作输出除非您计划最终使用操作系统管道或类似机制来连接控制台上的两个程序,但要保持简单!只需使用函数的返回值,当且仅当对于您的问题特别需要时才考虑管道。

阅读 cmets 后:在这种情况下,通过在控制台上打印并从另一个控制台读取来“连接”两个函数将是一个非常糟糕的主意,首先您必须掌握函数向每个函数返回值的方式另外,请相信我:您必须重新考虑您的程序!即使其他答案(严格来说)回答了您的原始问题,这绝对不是您应该做的。

【讨论】:

  • 因为我有一个很大的 for 循环列表,每个循环一个接一个,它们会按顺序将内容打印到屏幕上。然后,一旦输出看起来某种方式,我想再做一件事,但意识到仅仅把这个命令放在我所有的 for 循环之后并不能完成工作。因此,我将所有的 for 循环封装到一个函数中,然后使用 func() 调用该函数。当我输入 func() 时,不需要返回语句来打印我的输出,所以我想我应该在最后加上一个 return 语句……我试过了,但没有帮助。
  • 将所有输出累加到一个列表中,最后返回。打印结果不是想办法解决这个问题!
  • 我明白,但是如果我有一个 for 循环列表作为我的代码块,我会将 return 放在哪里,在每个 for 循环之后我会有一个 print 语句原来...
  • 不是打印每个值,而是将其附加到列表中,并在函数的最后返回列表
【解决方案3】:

只是为了好玩......因为 OP 要求它

import StringIO
import sys
def func1():
    for i in range(1,10):
        print "some stuff %d"%i

def func2(func):
    old_std = sys.stdout
    sys.stdout = StringIO.StringIO()
    try:
        func()
        return sys.stdout.getvalue().splitlines()

    finally:
        sys.stdout = old_std


print func2(func1)

【讨论】:

    【解决方案4】:

    您需要 return 函数中的一个值。这可用于将值分配给另一个变量。

    假设我定义了一些函数doubleThis,它将使输入加倍

    def doubleThis(x):
        print 'this is x :', x
        return x * 2    # note the return keyword
    

    现在我可以使用3 调用该函数,它按预期返回6

    >>> doubleThis(3)
    this is x : 3
    6
    

    现在我有另一个函数 subtractOne,它返回输入值,减 1。

    def subtractOne(i):
        print 'this is i :', i
        return i - 1
    

    现在回答您的问题。请注意,我们可以调用第一个函数作为第二个函数的输入,因为它有一个return 值。

    >>> subtractOne(doubleThis(3))
    this is x : 3
    this is i : 6
    5
    

    【讨论】: