Print expression and also echo it

大憨熊 提交于 2020-01-06 06:04:32

问题


I mean to define a function print_echo that replaces print, such that in addition to printing the result of an expression it prints the expression itself.

If I simply pass the expression as a string and use eval inside print_echo, it will not know any variable local to the caller function. My current code is

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

But when using

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

I get (no surprise)

NameError: name 'a' is not defined

I mean to get

    a => 2 <type 'int'>

I conceived two ways of working around this.

  1. Use a Python like alternative for C preprocessor macros. Something like C Preprocessor Macro equivalent for Python

  2. Pass all local variables to print_echo. Something like Passing all arguments of a function to another function

Since I find inconvenient aspects for each of the two, Is there any alternative to these?

Note that expr is a generic expression, not necessarily the name of a variable.


回答1:


eval() only takes the global namespace, and the namespace local to where it is called, into account.

In your case, you need the namespace of where print_echo is called (i.e., the "parent" namespace of where eval is called) as the local namespace, which you can get by using the inspect module and pass to eval as an argument.

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 output:

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



回答2:


Important Note: There can be more error handling to this case. For more info, you can see inspect and explore it further. 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 ) ) )


来源:https://stackoverflow.com/questions/52987211/print-expression-and-also-echo-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!