功能打印生成器 [英] Generator from function prints

查看:73
本文介绍了功能打印生成器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此刻,我有一个 flask 小项目,它调用了另一个python文件.我完全知道,这种方式有点糟糕,因此,我想将其交换为函数调用,同时保持将打印品打印到网站上.

At the moment I have a little flask project that calls another python file. I'm fully aware that this way is kinda awful, and so, I want to swap it for a function call while maintaining the prints getting yelded to the website.

def get_Checks():
    root = request.url_root

    def func():
        yield ("Inicio <br>")
        with subprocess.Popen(r"python somefile.py", stdout=subprocess.PIPE, bufsize=1,
                              universal_newlines=True) as p:
            for line in p.stdout:
                yield (line + "<br>")

    return Response(func())

我试图直接用函数替换文件调用,但是它只是将其打印到控制台上.

I've tryed to replace the file call with the function directly but it just prints it to the console.

非常感谢您能提供的任何帮助.

I really appreciate any help you can provide.

推荐答案

假定您要抓取的所有打印都在同一模块中完成,则可以猴子修补程序的 print 功能.其他模块.在下面的示例中,抓取完成后,我使用上下文管理器还原了原始打印功能.

Assuming that all the printing you want to grab is done within the same module, You can monkey-patch the print function of the other module. In the example below, I use a context manager to revert the original print function after the grabbing is done.

这是 mod1 ,是功能异常的模块.

This is mod1, the module with the misbehaving function.

def bogus_function():
    print('Hello World!')
    print('Line 2')

这是 mod2 ,使用 mod1.bogus_function()

import io
import functools
import contextlib

import mod1

@contextlib.contextmanager
def grab_stdout(module, fd):
    def monkey_print(*args, **kwargs):
        kwargs['file'] = fd
        print(*args, **kwargs)

    setattr(module, 'print', monkey_print)
    try:
        yield
    finally:
        setattr(module, 'print', print)

def line_generator():
    fd = io.StringIO()
    with grab_stdout(mod1, fd):
        mod1.bogus_function()
    fd.seek(0)

    for line in fd:
        yield line.rstrip('\r\n') + '<br>'

for t in enumerate(line_generator()):
    print('line %d: %r' % t)

grab_stdout()上下文管理器将 module 的打印调用重定向到类似文件的对象 fd .在函数 line_generator()中, grab_stdout()用于将 bogus_function 的打印输出存储在 StringIO 中对象 fd .其余的应该不言自明.

The grab_stdout() context manager redirects print calls of module to the file-like object fd. In the function line_generator(), grab_stdout() is used to store the print output of bogus_function in the StringIO object fd. The rest should be self-explanatory.

如果您不确切知道是否在该函数的调用树中的其他模块中调用了print,则可以按以下方式修改 grab_stdout :

If you don't know exactly whether print is called in other modules in the call tree of the function in question, you can modify grab_stdout as follows:

import builtins
print_orig = builtins.print

@contextlib.contextmanager
def grab_stdout_global(fd):
    def monkey_print(*args, **kwargs):
        kwargs['file'] = fd
        print_orig(*args, **kwargs)

    builtins.print = monkey_print
    try:
        yield
    finally:
        builtins.print = print_orig

这篇关于功能打印生成器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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