Распечатать выражение, а также повторить его - PullRequest
0 голосов
/ 25 октября 2018

Я имею в виду определение функции 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. Использовать альтернативу Python для макросов препроцессора C.Что-то вроде C Макропроцессор препроцессора для Python

  2. Передать все локальные переменные в print_echo.Что-то вроде Передача всех аргументов функции в другую функцию

Поскольку я нахожу неудобные аспекты для каждого из них, Есть ли альтернатива этим?

Обратите внимание, что выражение является обобщенным выражением, а не обязательно именем переменной.

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

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'>
0 голосов
/ 25 октября 2018

Важное примечание: в этом случае может быть больше обработки ошибок.Для получения дополнительной информации вы можете увидеть 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 ) ) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...