Более простой способ создать словарь отдельных переменных? - PullRequest
217 голосов
/ 31 марта 2010

Я хотел бы иметь возможность получить имя переменной в виде строки, но я не знаю, обладает ли Python такими возможностями самоанализа. Что-то вроде:

>>> print(my_var.__name__)
'my_var'

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

bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict 
{'foo': False, 'bar': True}

Но я бы хотел что-то более автоматическое, чем это.

Python имеет locals() и vars(), так что я думаю, что есть способ.

Ответы [ 25 ]

1 голос
/ 18 сентября 2016

На python3 эта функция получит самое внешнее имя в стеке:

import inspect


def retrieve_name(var):
        """
        Gets the name of var. Does it from the out most frame inner-wards.
        :param var: variable to get name from.
        :return: string
        """
        for fi in reversed(inspect.stack()):
            names = [var_name for var_name, var_val in fi.frame.f_locals.items() if var_val is var]
            if len(names) > 0:
                return names[0]

Это полезно в любом месте кода. Обходит стэк в обратном порядке в поисках первого совпадения.

1 голос
/ 09 февраля 2013

В python 2.7 и новее есть также словарное понимание, которое делает его немного короче. Если возможно, я бы использовал getattr вместо eval (eval is evil), как в верхнем ответе. Самость может быть любым объектом, контекст которого вы видите. Это может быть объект или locals = locals () и т. Д.

{name: getattr(self, name) for name in ['some', 'vars', 'here]}
0 голосов
/ 19 октября 2016
>>> a = 1
>>> b = 1
>>> id(a)
34120408
>>> id(b)
34120408
>>> a is b
True
>>> id(a) == id(b)
True

таким образом получите varname для 'a' или 'b'.

0 голосов
/ 31 мая 2018

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

def get_var_name(**kwargs):
    """get variable name
        get_var_name(var = var)
    Returns:
        [str] -- var name
    """
    return list(kwargs.keys())[0]
0 голосов
/ 22 декабря 2017

Хотя это, вероятно, ужасная идея, она соответствует той же схеме, что и ответ rlotun, но чаще возвращает правильный результат.

import inspect
def getVarName(getvar):
  frame = inspect.currentframe()
  callerLocals = frame.f_back.f_locals
  for k, v in list(callerLocals.items()):
    if v is getvar():
      callerLocals.pop(k)
      try:
        getvar()
        callerLocals[k] = v
      except NameError:
        callerLocals[k] = v
        del frame
        return k
  del frame

Вы называете это так:

bar = True
foo = False
bean = False
fooName = getVarName(lambda: foo)
print(fooName) # prints "foo"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...