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

如何对变量做同样的事情呢?与函数相反,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] 

当前回答

>> my_var = 5
>> my_var_name = [ k for k,v in locals().items() if v == my_var][0]
>> my_var_name 
'my_var'

如果myvar指向另一个变量,如果你得到一个错误,试试这个(由@mherzog建议)-

 >> my_var = 5
>> my_var_name = [ k for k,v in locals().items() if v is my_var][0]
>> my_var_name 
'my_var'

locals() -返回包含当前作用域局部变量的字典。 通过遍历这个字典,我们可以检查值等于定义变量的键,只需提取键就可以得到字符串格式的变量文本。

From(稍作改动后) https://www.tutorialspoint.com/How-to-get-a-variable-name-as-a-string-in-Python

其他回答

下面的方法将不会返回变量的名称,但如果变量在全局作用域可用,则使用此方法可以轻松创建数据帧。

class CustomDict(dict):
    def __add__(self, other):
        return CustomDict({**self, **other})

class GlobalBase(type):
    def __getattr__(cls, key):
        return CustomDict({key: globals()[key]})

    def __getitem__(cls, keys):
        return CustomDict({key: globals()[key] for key in keys})

class G(metaclass=GlobalBase):
    pass

x, y, z = 0, 1, 2

print('method 1:', G['x', 'y', 'z']) # Outcome: method 1: {'x': 0, 'y': 1, 'z': 2}
print('method 2:', G.x + G.y + G.z) # Outcome: method 2: {'x': 0, 'y': 1, 'z': 2}

A = [0, 1]
B = [1, 2]
pd.DataFrame(G.A + G.B) # It will return a data frame with A and B columns

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

定义函数:

# 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
>>> locals()['foo']
{}
>>> globals()['foo']
{}

如果你想写你自己的函数,你可以这样做,你可以检查一个局部变量定义,然后检查全局变量。如果没有找到,可以比较id(),看看变量是否指向内存中的相同位置。

如果你的变量在一个类中,你可以使用className.dict.keys()或vars(self)来查看你的变量是否已经被定义。

在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]

它在代码的任何地方都有用。遍历反向堆栈,寻找第一个匹配项。

我不相信这是可能的。考虑下面的例子:

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

a和b指向同一个对象,但是对象不知道哪些变量指向它。