我已经读了如何获得一个函数名作为字符串?。

如何对变量做同样的事情呢?与函数相反,Python变量没有__name__属性。

换句话说,如果我有一个变量,比如:

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

我正在寻找一个函数/属性,例如retrieve_name(),以便从这个列表中创建一个DataFrame in 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] 

当前回答

如果有两个值相同的变量,前面的一些情况会失败。所以提醒它很方便:

定义函数:

# Variable to string of variable name

def var_name(variable,i=0):

  results = []
  for name in globals():   
     if eval(name) == variable:
       results.append(name)

  if len(results) > 1:
    print('Warning:' )
    print('   var_name() has found',len(results), 'possible outcomes.')
    print('   Please choose the suitable parameter "i". Where "i" is the index')
    print('   that matches your choice from the list below.')
    print('  ',results) ; print('')

  return results[i]

Use:

var_1 = 10
var_name(var_1) # Output will be "var_1"

如果你有两个相同值的变量,比如var_1 = 8和var_2 = 8,那么就会出现一个警告。

var_1 = 8
var_2 = 8
var_name(var_2)  # Output will be "var_1" too but Warning will appear

其他回答

您可以尝试以下方法来检索您定义的函数的名称(但不适用于内置函数):

import re
def retrieve_name(func):
    return re.match("<function\s+(\w+)\s+at.*", str(func)).group(1)

def foo(x):
    return x**2

print(retrieve_name(foo))
# foo

获取实例变量的名称是完全可能的,只要它是类的属性。

这是我从Brett Slatkin的《Effective Python》中得到的。希望它能帮助到一些人:

类必须实现get、set和set_name dunder方法,它们是“描述符协议”的一部分。

当我运行它时,这是有效的:

class FieldThatKnowsItsName():
    def __init__(self):
        self.name = None
        self._value= None
        self.owner = None
 
    def __set_name__(self, owner, name):
        self.name = name
        self.owner = owner
        self.owner.fields[self.name] = self

    def __get__(self, instance, instance_type):
        return self

    def __set__(self, instance, value):
        self = value

class SuperTable:
    fields = {}
    field_1=FieldThatKnowsItsName()
    field_2=FieldThatKnowsItsName()

table = SuperTable()
print(table.field_1.name)
print(table.field_2.name)

然后,您可以根据需要添加方法或扩展数据类型。

作为奖励,set_name(self, owner, name) dunder也传递父实例,因此Field类实例可以向父实例注册自己。

这是我从Brett Slatkin的《Effective Python》中得到的。我花了一段时间才弄清楚如何实现。

iDilip的答案压缩版:

import inspect
def varname(x):
  return [k for k,v in inspect.currentframe().f_back.f_locals.items() if v is x][0]

hi = 123
print(varname(hi))

这是另一种基于输入变量内容的方法:

(它返回第一个与输入变量匹配的变量名,否则为None。可以修改它,以获得所有与输入变量具有相同内容的变量名)

def retrieve_name(x, Vars=vars()):
    for k in Vars:
        if isinstance(x, type(Vars[k])):
            if x is Vars[k]:
                return k
    return None

我认为在Python中很难做到这一点,因为一个简单的事实是,你永远不会不知道你正在使用的变量的名称。所以,在他的例子中,你可以这样做:

而不是:

list_of_dicts = [n_jobs, users, queues, priorities]

dict_of_dicts = {"n_jobs" : n_jobs, "users" : users, "queues" : queues, "priorities" : priorities}