【问题标题】:Print expression and also echo it打印表达式并回显它
【发布时间】:2019-03-29 22:39:44
【问题描述】:

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

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

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. 使用类似于 Python 的替代 C 预处理器宏。 类似C Preprocessor Macro equivalent for Python

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

由于我发现两者都有不便之处, 这些有什么替代品吗?

注意 expr 是一个泛型表达式,不一定是变量名。

【问题讨论】:

  • 我想我明白了,但是你能提供一个玩具例子来说明所需的输入和输出吗?
  • @Chris_Rands 是对的。给我们一些例子来更好地理解。根据我的理解,回溯可能会有所帮助。请参阅此答案,stackoverflow.com/a/2553524/2895956
  • @Chris_Rands - 我从手机发布,因此很难格式化和添加我在 PC 中的代码。现在我完成了。
  • @SujayKumar - 我看不清楚你的链接在这里有什么帮助。
  • 无法复制。对我来说,这可以按您的预期工作。你使用的是什么 Python 版本? (编辑:它适用于 Python 2.7 和 3.5)

标签: python eval preprocessor


【解决方案1】:

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

【讨论】:

  • 最好使用外框的全局变量 (f_globals) 而不是 print_echo 的全局变量(在您的示例中恰好是相同的)。
  • @Dunes 你的意思是用f_back.f_globals替换globals()
【解决方案2】:

重要提示:可以对这种情况进行更多错误处理。 有关详细信息,您可以查看 inspect 并进一步探索。 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 ) ) )

【讨论】:

    猜你喜欢
    • 2014-09-29
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2019-06-09
    • 2021-04-26
    • 1970-01-01
    相关资源
    最近更新 更多