如何在Python中对函数输出执行某些操作?

0 投票
4 回答
679 浏览
提问于 2025-04-18 17:51

我想让一个函数的输出像我的输入一样使用。我的目标是从旧的输出中生成新的输出。

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

def func():

    BLOCK OF CODE

func()

这个函数里没有返回值,也没有括号里的参数。当我输入 func() 来调用我的函数时,得到了我想要的输出,就是一堆打印的内容。现在我想对这个输出做点什么,以便得到另一个输出。

我只是想把一个函数的输出“管道”到另一个函数的输入中(或者,如果可能的话,甚至不想创建另一个函数,而是直接做点别的)。我查了一下 Python 3 写入管道,但没有找到帮助。我还尝试定义另一个函数,并把前面的函数作为参数传进去,但也没成功:

def another_func(func):
    print another_statement

another_func(func)

我还尝试做了一个闭包(这“有点”有效,因为至少它打印了与 func() 一样的内容,但还是不太令人满意):

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

another_func()

最后,我尝试设计一个装饰器和一个嵌套函数来实现这个目标,但我的函数里没有参数,这真的让我困惑(根本没打印任何东西)。

有没有什么建议,可以让我像使用输入一样操作一个函数的输出,从而创建新的输出呢?

4 个回答

0

你需要在你的函数中使用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
1

纯粹是为了好玩……因为提问的人想要这个

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)
1

从函数中返回你想要的值,而不是把值打印到控制台上。你可以把它们作为字符串、数字、列表或其他合适的类型返回。否则,如果一开始没有输出,你怎么能把一个函数的输出“连接”到另一个函数的输入呢?

当然,打印到控制台并不算真正的输出,除非你打算用操作系统的管道或者类似的方式把两个程序连接起来。但为了简单起见,还是直接使用函数的返回值吧。如果你的问题确实需要管道的处理,再去考虑这些也不迟。

看完评论后发现,通过一个函数在控制台上打印,然后另一个函数从控制台读取来“连接”这两个函数,实际上是个很糟糕的主意。你首先得理解函数是如何相互返回值的,相信我,你必须重新思考你的程序!虽然其他回答(严格来说)回答了你最初的问题,但那绝对不是你应该采取的做法。

2

你可以通过使用装饰器来重定向标准输出(stdout):

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')

不过,我想不出有什么好的理由让你想这样做。

(其实,这并不是完全正确;在编写用户输入输出的单元测试时,这个方法很方便,比如在软件工程课程中测试学生的作业。不过,我真的怀疑提问者想要的就是这个。)

撰写回答