Получение имени переменной в виде строки

В этом разделе обсуждается, как получить имя функции в виде строки в Python: как получить имя функции в виде строки в Python?

Как я могу сделать то же самое для переменной? (обратите внимание, что переменные Python не имеют атрибута __name__ , по крайней мере, в Python 2.7.x )

Другими словами, если у меня есть переменная, такая как:

 foo = dict() foo['bar'] = 2 

Я ищу функцию / атрибут, например retrieve_name :

 retrieve_name(foo) 

который возвращает строку 'foo'

Обновить:

Поскольку люди спрашивают, почему я хочу это сделать, вот пример. Я хотел бы создать DataFrame в Pandas из этого списка , где имена столбцов даются именами фактических словарей:

 # List of dictionaries for my DataFrame list_of_dicts = [n_jobs, users, queues, priorities] 

  • Как выбрать каталог и сохранить местоположение с помощью tkinter в Python
  • Что означает синтаксис «variable // = a value» в Python?
  • Почему импорт не всегда импортирует вложенные пакеты?
  • Запуск интерактивного Bash с помощью popen и выделенного TTY Python
  • Как рассчитать следующую пятницу в Python?
  • Литералы Unicode, которые работают в python 3 и 2
  • Как проверить, является ли переменная строкой с совместимостью с python 2 и 3
  • PyGame Sprites Иногда не рисует
  • 10 Solutions collect form web for “Получение имени переменной в виде строки”

    Единственными объектами в Python, которые имеют канонические имена, являются модули, функции и классы, и, конечно же, нет никакой гарантии, что это каноническое имя имеет какое-либо значение в любом пространстве имен после того, как функция или класс будет определен или импортирован модуль. Эти имена также могут быть изменены после создания объектов, поэтому они не всегда могут быть особенно надежными.

    То, что вы хотите сделать, невозможно без рекурсивной ходьбы по дереву именованных объектов ; имя является односторонней ссылкой на объект. Обычный или садовый объект Python не содержит ссылок на его имена. Представьте себе, что если каждое целое число, каждый dict, каждый список, каждый Boolean должен содержать список строк, которые представляли имена, которые ссылались на него! Это был бы кошмар внедрения, с небольшим преимуществом для программиста.

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

    Кто-то упомянул об этом ответе, что вам, возможно, придется ходить по стеклу и проверять локальные и глобальные локаторы для поиска foo , но если foo назначается в области, где вы вызываете эту функцию retrieve_name , вы можете использовать current frame для получения вы все эти локальные переменные. Мое объяснение может быть немного слишком многословным (возможно, я должен был использовать «foo» меньше слов), но вот как он будет выглядеть в коде (обратите внимание, что если имеется более одной переменной, присвоенной одному и тому же значению, вы будете получить оба этих имени переменных):

     import inspect x,y,z = 1,2,3 def retrieve_name(var): callers_local_vars = inspect.currentframe().f_back.f_locals.items() return [var_name for var_name, var_val in callers_local_vars if var_val is var] print retrieve_name(y) 

    Я не считаю, что это возможно. Рассмотрим следующий пример:

     >>> a = [] >>> b = a >>> id(a) 140031712435664 >>> id(b) 140031712435664 

    А и b указывают на один и тот же объект. Он (объект) не знает, какие переменные указывают на него.

     def name(**variables): return [x for x in variables] 

    Он используется следующим образом:

     name(variable=variable) 

    Вот один из подходов. Я бы не рекомендовал это ни для чего важного, потому что он будет довольно хрупким. Но это может быть сделано.

    Создайте функцию, которая использует модуль inspect чтобы найти исходный код, который вызвал его. Затем вы можете проанализировать исходный код, чтобы идентифицировать имена переменных, которые вы хотите получить. Например, вот функция, называемая autodict которая принимает список переменных и возвращает имена переменных сопоставления словаря их значениям. Например:

     x = 'foo' y = 'bar' d = autodict(x, y) print d 

    Даст:

     {'x': 'foo', 'y': 'bar'} 

    Проверка самого исходного кода лучше, чем поиск по locals() или globals() потому что последний подход не говорит вам, какие из переменных являются теми, которые вы хотите.

    Во всяком случае, вот код:

     def autodict(*args): get_rid_of = ['autodict(', ',', ')', '\n'] calling_code = inspect.getouterframes(inspect.currentframe())[1][4][0] calling_code = calling_code[calling_code.index('autodict'):] for garbage in get_rid_of: calling_code = calling_code.replace(garbage, '') var_names, var_values = calling_code.split(), args dyn_dict = {var_name: var_value for var_name, var_value in zip(var_names, var_values)} return dyn_dict 

    Действие происходит в строке с inspect.getouterframes , которая возвращает строку в коде, который называется autodict .

    Очевидным недостатком такого рода магии является то, что он делает предположения о том, как структурирован исходный код. И, конечно, это не сработает, если он запущен внутри интерпретатора.

    В Python ключевые слова def и class свяжут определенное имя с объектом, который они определяют (функция или класс). Аналогичным образом, модули получают имя из-за того, что в файловой системе называют что-то конкретное. Во всех трех случаях существует очевидный способ назначить «каноническое» имя рассматриваемому объекту.

    Однако для других видов объектов такое каноническое имя может просто не существовать . Например, рассмотрим элементы списка. Элементы в списке не называются индивидуально, и вполне возможно, что единственный способ ссылаться на них в программе – это использовать индексы списка в содержащем списке. Если такой список объектов был передан в вашу функцию, вы не могли бы назначить значащие идентификаторы для значений.

    Python не сохраняет имя в левой части назначения в назначенный объект, потому что:

    1. Это потребовало бы выяснить, какое имя было «каноническим» среди нескольких конфликтующих объектов,
    2. Это не имеет смысла для объектов, которые никогда не назначаются явному имени переменной,
    3. Это было бы крайне неэффективно,
    4. Буквально ни один другой язык не существует.

    Так, например, функции, определенные с помощью lambda , всегда будут иметь имя « <lambda> , а не конкретное имя функции.

    Лучшим подходом было бы просто попросить вызывающего абонента передать (необязательный) список имен. Если ввести '...','...' слишком громоздко, вы можете принять, например, одну строку, содержащую список имен, разделенных запятыми (например, namedtuple ).

    На 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] 

    Это полезно в любом месте кода. Перемещает обратную стек, ищущую первый матч.

     >>> locals()['foo'] {} >>> globals()['foo'] {} 

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

    Если переменная находится в классе, вы можете использовать className. dict .keys () или vars (self), чтобы узнать, определена ли ваша переменная.

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

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

    Вместо:

     list_of_dicts = [n_jobs, users, queues, priorities] dict_of_dicts = {"n_jobs" : n_jobs, "users" : users, "queues" : queues, "priorities" : priorities} 
    Interesting Posts

    MailChimp API 3.0 пакетная / массовая подписка

    Есть ли стандартный способ убедиться, что скрипт python будет интерпретироваться python2, а не python3?

    Numpy: Массив `arange`s

    Слить или выбросить генератор без зацикливания?

    Как увеличить количество подразделений для функций в `scipy.integrate.dblquad`?

    Объединить много строк json с входами pandon pandas

    Как избежать использования токенизатора предложения NLTK, разделяющего аббревиатуры?

    Как сохранить пользовательский категоризированный корпус в NLTK

    Как мне высмеять IMAP-сервер в Python, несмотря на крайнюю лень?

    Как ограничить трафик с помощью многоадресной рассылки по локальной сети

    Удалить текст между () и в python

    Как получить имена объектов, выбранные путем исключения функций в конвейере sklearn?

    Вход и использование файлов cookie в pycurl

    Почему csvwriter.writerow () помещает запятую после каждого символа?

    Как использовать viridis в matplotlib 1.4

    Python - лучший язык программирования в мире.