打印表达式并回显

时间:2018-10-25 10:35:31

标签: python eval preprocessor

我的意思是定义一个替换print_echo的函数print,这样,除了打印表达式的结果外,它还会打印表达式本身。

如果我只是将表达式作为字符串传递并在eval内使用print_echo,它将不知道调用方函数本地的任何变量。 我当前的代码是

def print_echo( expr ) :
    result = eval( expr )
    print( expr + ' => ' + str( result ) + ' ' + str( type( result ) ) )
    return

但是使用时

def my_func( params ) :
    a = 2
    print_echo( "a" )

我得到(毫不奇怪)

NameError: name 'a' is not defined

我的意思是

    a => 2 <type 'int'>

我构思了两种解决方法。

  1. 对C预处理器宏使用类似Python的替代方法。 像C Preprocessor Macro equivalent for Python

  2. 将所有局部变量传递给print_echo。 像Passing all arguments of a function to another function

由于我发现这两个方面都有不便之处, 这些还有其他选择吗?

请注意,expr是通用表达式,不一定是变量的名称。

2 个答案:

答案 0 :(得分:0)

重要说明:这种情况下可能会有更多错误处理。 有关更多信息,您可以查看检查并进一步进行探索。 https://docs.python.org/2/library/inspect.html

import inspect

# NOTE: this only prints the local variables to the function
def print_echo( *expr ) :

    frame = inspect.currentframe().f_back # see the previous frame and what all variable it's previous caller knows
    values = inspect.getargvalues(frame)[3]
    print values # just to understand what it is, remove it later
    for e in expr:
        try:
            result = values[e]
        except KeyError:
            eval(e) # see the globally defined variables, if not found local to previous function.
        print( str(e) + ' => ' + str( result ) + ' ' + str( type( result ) ) )

答案 1 :(得分:0)

eval()仅考虑全局命名空间以及调用它的本地命名空间。

在您的情况下,您需要调用print_echo的命名空间(即,调用eval的“父”命名空间)作为本地命名空间,可以通过使用inspect模块并作为参数传递给eval

import inspect

def print_echo(expr):
    outer_locals = inspect.currentframe().f_back.f_locals
    result = eval(expr, globals(), outer_locals)
    print(expr, '=>', result, type(result))

a = 2
print_echo('a')

def f():
    b = 3
    print_echo('b')

f()

Python 3输出:

a => 2 <class 'int'>
b => 3 <class 'int'>