2009-05-31 3 views
26

есть способ узнать, во время выполнения, имя переменной (из кода)? или забыли имена переменных во время компиляции (байт-код или нет)?Получение имени переменной в python во время выполнения?

например.

 
>>> vari = 15 
>>> print vari.~~name~~() 
'vari' 

примечание: я говорю о переменных простых типов данных (INT, ул, список ...)

+6

Вам не нужно вводить имя переменной, чтобы получить ее имя? –

+2

Да, это было 3 года назад, и я не помню, почему этот вопрос имел смысл. Но woa! он очень популярен, поэтому есть что-то в этом роде. –

+0

Вот пример использования: переменные foo, bar, baz есть, я хочу получить словарь точно так же, как {'foo': foo, 'bar': bar, 'baz': baz}. Конечно, я могу напечатать то, что я только что сделал, но не очень лаконично. 'locals()', на мой взгляд, передают слишком много информации, а не совершенны. То, что я ожидаю, это функция типа 'magic_func ([foo, bar, baz])', которая возвращает словарь, который я хочу – ZZY

ответ

2

здесь основная (может быть, странная) функция, которая показывает название его аргумента ... идея заключается в том, чтобы проанализировать код и поиск вызовов функции (добавлено в инициализации метода он может помочь найти имя экземпляра, хотя и с более сложным анализом кода)

def display(var): 
    import inspect, re 
    callingframe = inspect.currentframe().f_back 
    cntext = "".join(inspect.getframeinfo(callingframe, 5)[3]) #gets 5 lines 
    m = re.search("display\s+\(\s+(\w+)\s+\)", cntext, re.MULTILINE) 
    print m.group(1), type(var), var 

обратите внимание: получать несколько строк из кода вызова помогает в том случае, вызов был разделен, как в примере ниже:

display(
     my_var 
     ) 

но даст неожиданный результат на этом:

display(first_var) 
display(second_var) 

Если вы не имеете контроля над форматом вашего проекта вы можете улучшить код для обнаружения и управления различными ситуациями ...

В целом, я думаю, статический анализ кода может производить более надежный результат, но я слишком ленив, чтобы проверить это сейчас

10

имена переменных сохраняются в скомпилированный код (который, как например, dir встроенный может работа), но сопоставление происходит от имени к значению, а не наоборот. Так что, если есть несколько переменных, которые стоят всего, например, 23, нет возможности рассказать их друг от друга только по значению 23.

29

Имена переменных не забываются, вы можете получить доступ к переменным (и посмотреть, какие переменные у вас есть) путем интроспекции, например.

>>> i = 1 
>>> locals()["i"] 
1 

Однако, поскольку нет никаких указателей в Python, нет никакого способа ссылаться на переменную без фактического написания его имени. Поэтому, если вы хотите напечатать имя переменной и ее значение, вы можете пройти через locals() или аналогичную функцию. ([i] становится [1] и нет никакого способа, чтобы получить информацию о том, что на самом деле 1 пришли из i.)

+0

, это решает мой случай. затем я делаю обратный поиск их значений и нахожу их имена. Благодарю. –

+5

Трудная часть об этом заключается в том, что если у вас есть только «я», тогда невозможно найти его имя в 'locals()'. Рассмотрим 'i = 1; J = 1;». После этого locals() ["i"] являются locals() ["j"] '. Если все, что у вас есть, - это «i», тогда цикл через locals() приведет к тому, что в качестве имени будет найдено либо «i», либо «j». –

+1

D. Вероятно, намеревался сказать: «Если все, что у вас есть, это« 1' [...] » – akaihola

0

Только вчера я видел сообщение в блоге рабочий код, который делает именно это. Вот ссылка:

http://pyside.blogspot.com/2009/05/finding-objects-names.html

+0

« Извините, страницы, которую вы искали в этом блоге, не существует ». –

+2

@StuartWoodward: archive.org имеет копию: http://web.archive.org/web/20090624235438/http://pyside.blogspot.com/2009/05/finding-objects-names.html –

+0

Это будет также работает только в текущей форме, если он используется в файле 'main' python, если он импортирован, он откроет неправильный файл, поэтому его нужно будет адаптировать. – will

1

Я попробовал ссылку с поста выше не увенчались успехом: Googling вернулся этот.

http://pythonic.pocoo.org/2009/5/30/finding-objects-names

+0

За исключением того, что я поддержал это, это не обязательно «пост выше»: мы говорим о ответе @ piquadrat. – ptomato

3

Это будет работать для простых типов данных (улица, целый, дробный, список и т.д.)

def my_print(var_str) : 
    print var_str+':', globals()[var_str] 
+0

Просто нужно отметить, что если вы имеете, скажем 'ix = 200', вы вызываете эту функцию с помощью' my_print ("ix") '. – sdaau

4

Вот функция, я использую, чтобы напечатать значения переменных, она работает местные, а также глобалы:

import sys 
def print_var(var_name): 
    calling_frame = sys._getframe().f_back 
    var_val = calling_frame.f_locals.get(var_name, calling_frame.f_globals.get(var_name, None)) 
    print (var_name+':', str(var_val)) 

так следующий код:

global_var = 123 
def some_func(): 
    local_var = 456 
    print_var("global_var") 
    print_var("local_var") 
    print_var("some_func") 

some_func() 

производит:

global_var: 123 
local_var: 456 
some_func: <function some_func at 0x10065b488> 
+0

Это то, что я искал. Однако теперь мне любопытно, можно ли это расширить, чтобы работать для любого выражения, учитывая контекст, когда вызывается 'print_var'. Одним из вариантов использования было бы напечатать как имя, так и значение поля объекта (например, 'print_var ('myobject.x')') – anishpatel

+0

Это было не слишком сложно: https://gist.github.com/anishpatel/e32f9cdc1df55692f418 – anishpatel

2

Вы можете это сделать, это просто не красиво.

import inspect, sys 


def addVarToDict(d, variable): 
    lineNumber = inspect.currentframe().f_back.f_lineno 
    with open(sys.argv[0]) as f: 
     lines = f.read().split("\n") 

    line = lines[lineNumber-1] 

    varName = line.split("addVarToDict")[1].split("(")[1].split(",")[1].split(")")[0].strip() 
    d[varName] = variable 


d = {} 

a=1 

print d # {} 
addVarToDict(d,a) 
print d # {'a': 1} 
Смежные вопросы