如何查看命令运行结果? [英] How can I check command running result?

查看:35
本文介绍了如何查看命令运行结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在自定义的python解释器中,如果运行单个命令,我可以看到命令输出.
但是,如果我将命令放入文件并使用 execfile('file.py') 运行,除了打印命令,我什么也看不到.很难调试.
使用 execfile 命令运行时如何检查命令输出?

尝试了以下命令以确认 python 版本.

导入系统打印 sys.version_info[0],sys.version_info[1]2 7

解决方案

'command output' 并不是一个真正有效的术语.Python 交互式解释器将回显任何 表达式的结果语句,除非该表达式产生None.表达式语句是模块主体中仅包含单个表达式的顶级语句(与 其他简单语句,例如赋值或 import复合语句,例如 ifwhile.来自链接的文档:

<块引用>

在交互模式下,如果值不是None,则使用内置的repr()函数将其转换为字符串,并将结果字符串写入标准输出 [...] 单独一行.(生成 None 的表达式语句没有被写入,因此过程调用不会导致任何输出.)

脚本中这样做是不切实际的;如果脚本的用户不必解密打印到屏幕上的每一件小事,您将永远无法运行任何表达式语句.脚本通常希望控制打印的内容(例如,根本不打印任何内容,而是使用日志记录).

如果您使用 execfile() 运行脚本,您可以切换到将脚本解析为 抽象语法树,此时可以对表达式语句节点进行变换,添加打印.生成的转换后的 AST 可以直接提供给 compile() 函数,而 exec() 函数可以获取编译步骤的输出.

我会在此处使用传递给 exec() 的额外全局函数:

导入 ast类 ExprStatementPrinter(ast.NodeTransformer):def visit_Expr(self, node): # 表达式语句节点# 调用函数__print_expr_result__,传入表达式# 内容;用该调用替换原始表达式内容.new_value = ast.Call(ast.Name('__print_expr_result__', ast.Load()), # 作为全局加载[node.value], [], None, None) # node.value 是唯一的参数# 为了能够执行,我们需要设置lineno和coll_offset;只是# 重用 expr 节点的值,然后修复所有子节点node.value = ast.copy_location(new_value, node.value)返回 ast.fix_missing_locations(node)def print_expr_result(result):如果结果不是无:打印代表(结果)def execfile(文件名):以 open(filename) 作为源:树 = ast.parse(source.read())ExprStatementPrinter().visit(tree) # 就地更新树codeobj = compile(树,文件名,'exec')exec(codeobj,{'__print_expr_result__':print_expr_result})

我使用了双下划线系统"为打印函数定义名称以避免与脚本可能定义的任何内容发生冲突.

演示:

<预><代码>>>>示例 = '''\... 导入系统... sys.version_info[0],sys.version_info[1]... '你好,世界!'... None # 不应该被打印...'''>>>exec(example) # 没有输出>>>树 = ast.parse(示例)>>>ExprStatementPrinter().visit(tree)<_ast.Module 对象在 0x1024c14d0>>>>codeobj = compile(tree, '', 'exec')>>>exec(codeobj,{'__print_expr_result__':print_expr_result})(2, 7)'你好,世界!'

注意:这仅适用于您执行的顶级文件.任何导入的模块仍然会在没有转换的情况下运行(就像它们在 Python 交互式解释器中一样).您必须挂钩 __import__ 全局以拦截正常的导入机制.

Inside a customised python interpreter, if run single command, I can see the command output.
But if I put commands into a file and run with execfile('file.py'), except print command, I can't see anything. It's hard to debug.
How can I check command output when run with execfile command?

Tried below commands to confirm the python version.

import sys
print sys.version_info[0],sys.version_info[1]
2 7

解决方案

'command output' is not really a valid term. The Python interactive interpreter will echo the result of any expression statement, unless that expression produced None. An expression statement is a top-level statement in a module body that only contains a single expression (as opposed to other simple statements such as assignment or import or compound statements such as if or while. From the linked documentation:

In interactive mode, if the value is not None, it is converted to a string using the built-in repr() function and the resulting string is written to standard output [...] on a line by itself. (Expression statements yielding None are not written, so that procedure calls do not cause any output.)

Doing so in a script would not be practical; you'd never be able to run any expression statement without the user of the script having to then decipher every little thing printed to the screen. Scripts usually want to control what is printed (to the point of not printing anything at all, but using logging instead, for example).

If you are using execfile() to run scripts, you could switch to parsing the script into an abstract syntax tree, at which point you can transform the expression statement nodes to add printing. The resulting transformed AST can be fed directly to the compile() function, and the exec() function can take the output of the compilation step.

I'd use an extra global function passed to exec() here:

import ast

class ExprStatementPrinter(ast.NodeTransformer):
    def visit_Expr(self, node):  # expression statement node
        # call the function __print_expr_result__, passing in the expression
        # contents; replace the original expression contents with that call.
        new_value = ast.Call(
            ast.Name('__print_expr_result__', ast.Load()),  # load as a global
            [node.value], [], None, None)  # node.value is the only argument
        # to be able to execute, we need to set the lineno and coll_offset; just
        # reuse the values of the expr node, then fix up any children
        node.value = ast.copy_location(new_value, node.value)
        return ast.fix_missing_locations(node)

def print_expr_result(result):
    if result is not None:
        print repr(result)

def execfile(filename):
    with open(filename) as source:
        tree = ast.parse(source.read())
    ExprStatementPrinter().visit(tree)  # updates the tree in-place
    codeobj = compile(tree, filename, 'exec')
    exec(codeobj, {'__print_expr_result__': print_expr_result})

I used a double-underscore 'system' defined name for the print function to avoid collisions with anything the script might have defined.

Demo:

>>> example = '''\
... import sys
... sys.version_info[0],sys.version_info[1]
... 'Hello world!'
... None  # should not be printed
... '''
>>> exec(example)  # no output
>>> tree = ast.parse(example)
>>> ExprStatementPrinter().visit(tree)
<_ast.Module object at 0x1024c14d0>
>>> codeobj = compile(tree, '', 'exec')
>>> exec(codeobj, {'__print_expr_result__': print_expr_result})
(2, 7)
'Hello world!'

Note: this only applies to the top-level file you execute. Any imported modules are still going to be run without transformation (just like they would in the Python interactive interpreter). You'd have to hook into the __import__ global to intercept the normal importing machinery.

这篇关于如何查看命令运行结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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