Этот поток обсуждает, как получить имя функции в виде строки в Python: Как получить имя функции в виде строки?
Как я могу сделать то же самое для переменной? В отличие от функций переменные Python не имеют __name__
атрибута.
Другими словами, если у меня есть переменная, такая как:
foo = dict()
foo['bar'] = 2
Я ищу функцию / атрибут, например retrieve_name()
, для создания DataFrame в Pandas из этого списка , где имена столбцов задаются именами фактических словарей:
# List of dictionaries for my DataFrame
list_of_dicts = [n_jobs, users, queues, priorities]
columns = [retrieve_name(d) for d in list_of_dicts]
pip3 install python-varname==0.1.5
; импортировано с использованиемfrom varname import nameof
test = {}
print(varname.nameof(test))
for i in [0]:
print(varname.nameof(test))
первый отпечаток даетtest
, отпечаток в цикле повышаетсяVarnameRetrievingError: Callee's node cannot be detected.
v0.2.0
Единственными объектами в Python, которые имеют канонические имена, являются модули, функции и классы, и, конечно, нет никакой гарантии, что это каноническое имя будет иметь какое-либо значение в любом пространстве имен после определения функции или класса или импорта модуля. Эти имена также могут быть изменены после создания объектов, поэтому они не всегда могут быть особенно заслуживающими доверия.
То, что вы хотите сделать, невозможно без рекурсивного обхода дерева именованных объектов ; имя является односторонней ссылкой на объект. Обычный или разнообразный объект Python не содержит ссылок на его имена. Представьте, что каждому целому числу, каждому дикту, каждому списку, каждому логическому значению требуется поддерживать список строк, которые представляют имена, ссылающиеся на него! Это был бы кошмар реализации, с небольшой пользой для программиста.
источник
__name__
всегда можно изменить, что означает, что «каноническое» имя не может быть именем, которое можно использовать для получения объекта (например, при динамическом создании классов).Даже если значения переменных не указывают обратно на имя, у вас есть доступ к списку каждой назначенной переменной и ее значению, поэтому я удивлен, что только один человек предложил перебрать там поиск вашего имени переменной.
Кто-то упомянул в этом ответе, что вам, возможно, придется пройтись по стеку и проверить все локальные и глобальные переменные, чтобы найти их
foo
, но еслиfoo
это назначено в области, в которой вы вызываете этуretrieve_name
функцию, вы можете использоватьinspect
s,current frame
чтобы получить все эти локальные переменные. ,Мое объяснение может быть немного слишком многословным (возможно, мне следовало бы использовать меньше слов "foo"), но вот как это будет выглядеть в коде ( обратите внимание, что если более одной переменной присвоено одно и то же значение, вы будете получить оба из этих имен переменных ):
Если вы вызываете эту функцию из другой функции, что-то вроде:
И вы хотите
baz
вместо этогоbar
, вам просто нужно вернуться назад. Это можно сделать, добавив дополнительный.f_back
вcaller_local_vars
инициализации.Смотрите пример здесь: ideone
источник
import hooks
,ironpython
иjython
a, b = 2, 2
,retrieve_name(a)
иretrieve_name(b)
оба вернутся['a', 'b']
или['b', 'a']
true
дляis
сравненияdef foo(bar): retrieve_name(bar)
, всегда будет возвращать бар, но что, если вы хотитеfoo(baz)
вернутьсяbaz
) вместоbar
?callers_local_vars
чтобы переместиться на одну область назад, чтобы она смотрела на область вызоваfoo
. Измените строку наinspect.currentframe().f_back.f_back.f_locals.items()
(обратите внимание на дополнительнуюf_back
).В Python 3.8 можно просто использовать функцию отладки f-строки:
источник
f'{foo=}'.split('=')[0].split('.')[-1]
На python3 эта функция получит самое внешнее имя в стеке:
Это полезно в любом месте кода. Пройдет обратный стек в поисках первого совпадения.
источник
retrieve_name(SomeClass.some_attribute)
это не работает. Можете ли вы помочь в этом?stop_on_error
Я не верю, что это возможно. Рассмотрим следующий пример:
a
Иb
указывают на тот же объект, но объект не может знать , какие переменные указывают на него.источник
Используется так:
источник
name(variable=variable)
будет выводить['variable']
, а использование неname(variable=another_variable)
будет выводить, а скорее .['another_variable']
['variable']
>>> a = []
>>> b = a
>>> name(a=b)
['a']
>>> name(b=a)
['b']
`Вот один из подходов. Я не рекомендовал бы это для чего-то важного, потому что это будет довольно хрупким. Но это может быть сделано.
Создайте функцию, которая использует
inspect
модуль для поиска исходного кода, который его вызвал. Затем вы можете проанализировать исходный код, чтобы определить имена переменных, которые вы хотите получить. Например, вот вызываемая функция,autodict
которая принимает список переменных и возвращает имена переменных словаря, отображающие их значения. Например:Даст:
Проверка самого исходного кода лучше, чем поиск с помощью
locals()
или,globals()
поскольку последний подход не говорит вам, какие из переменных вам нужны.В любом случае, вот код:
Действие происходит в строке с
inspect.getouterframes
, которая возвращает строку в коде, который вызвалautodict
.Очевидным недостатком этого вида магии является то, что она делает предположения о том, как структурирован исходный код. И, конечно, он не будет работать вообще, если он запускается внутри интерпретатора.
источник
Я написал пакет волшебства, чтобы творить магию такого рода. Ты можешь написать:
и передать это конструктору dataframe. Это эквивалентно:
источник
Если вы хотите написать свою собственную функцию, это можно сделать так, чтобы вы могли проверить переменную, определенную в локальных, а затем проверить глобальные переменные. Если ничего не найдено, вы можете сравнить id (), чтобы увидеть, указывает ли переменная на то же место в памяти.
Если ваша переменная находится в классе, вы можете использовать className. dict .keys () или vars (self), чтобы увидеть, была ли определена ваша переменная.
источник
locals
иglobals
... и вы рискуете ошибиться, если ничего не существует. Это тонна работы без реальной выгоды.В Python
def
иclass
ключевые слова будут связывать имя , характерным для конкретного объекта они определяют (функция или класс). Аналогичным образом, модулям присваивается имя в силу того, что они называются чем-то конкретным в файловой системе. Во всех трех случаях существует очевидный способ присвоения «канонического» имени рассматриваемому объекту.Однако для других типов объектов такое каноническое имя может просто не существовать . Например, рассмотрим элементы списка. Элементы в списке не имеют индивидуального имени, и вполне возможно, что единственный способ ссылаться на них в программе - это использовать индексы списка в содержащем списке. Если такой список объектов был передан в вашу функцию, вы не сможете назначить значимые идентификаторы значениям.
Python не сохраняет имя в левой части назначения в назначенном объекте, потому что:
Так, например, функции, определенные с использованием
lambda
всегда будут иметь «имя»<lambda>
, а не конкретное имя функции.Наилучшим подходом было бы просто попросить звонящего передать (необязательный) список имен. Если ввод
'...','...'
слишком громоздок, вы можете принять, например, одну строку, содержащую список имен через запятую (как, например,namedtuple
делает).источник
Я думаю, что это трудно сделать в Python из-за того простого факта, что вы никогда не узнаете имя используемой переменной. Итак, в его примере вы могли бы сделать:
Вместо того:
источник
просто еще один способ сделать это на основе содержимого входной переменной:
(он возвращает имя первой переменной, которая соответствует входной переменной, в противном случае None. Можно изменить его, чтобы получить все имена переменных, которые имеют то же содержимое, что и входная переменная)
источник
Эта функция напечатает имя переменной со значением:
источник
locals () - возвращает словарь, содержащий локальные переменные текущей области. перебирая этот словарь, мы можем проверить ключ, который имеет значение, равное определенной переменной, простое извлечение ключа даст нам текст переменной в строковом формате.
от (после небольшого изменения) https://www.tutorialspoint.com/How-to-get-a-variable-name-as-a-string-in-Python
источник
У меня есть метод, и пока он не самый эффективный ... он работает! (и это не включает в себя какие-либо модные модули).
В основном это сравнивает идентификатор переменного для глобал () идентификаторы переменных , а затем возвращает имя Спичечного.
источник
Если цель состоит в том, чтобы помочь вам отслеживать ваши переменные, вы можете написать простую функцию, которая помечает переменную и возвращает ее значение и тип. Например, предположим, что i_f = 3,01, и вы округлите его до целого числа i_n для использования в коде, а затем потребуется строка i_s, которая войдет в отчет.
Это печатает в окно при каждом вызове для целей отладки, а также выдает строку для письменного отчета. Единственным недостатком является то, что вы должны вводить переменную дважды каждый раз, когда вы вызываете функцию.
Я новичок в Python и нашел этот очень полезный способ записывать свои усилия во время программирования и пытаться справиться со всеми объектами в Python. Один недостаток заключается в том, что whatis () завершается ошибкой, если вызывает функцию, описанную вне процедуры, в которой он используется. Например, int (i_f) был допустимым вызовом функции только потому, что функция int известна Python. Вы можете вызвать whatis (), используя int (i_f ** 2), но если по какой-то странной причине вы решите определить функцию с именем int_squared, она должна быть объявлена внутри процедуры, где используется whatis ().
источник
Может быть, это может быть полезно:
Функция просматривает список идентификаторов значений из глобальной области (пространство имен может быть отредактировано), находит индекс требуемой / требуемой переменной или функции на основе ее идентификатора, а затем возвращает имя из списка глобальных имен на основе по приобретенному индексу.
источник
Следующий метод не возвращает имя переменной, но с помощью этого метода вы можете легко создать фрейм данных, если переменная доступна в глобальной области видимости.
источник
Для констант вы можете использовать enum, который поддерживает получение его имени.
источник
Я пытаюсь получить имя от осмотра местных жителей, но он не может обработать var like a [1], b.val. После этого у меня появилась новая идея - получить имя var из кода, и я попробую его succ! код как ниже:
источник
Вы можете попробовать следующее, чтобы получить имя функции, которую вы определили (хотя она не работает для встроенных функций):
источник