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

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

当前回答

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

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

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

其他回答

这里有一种方法。我不建议在任何重要的事情上使用它,因为它会很脆。但这是可以做到的。

创建一个使用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中唯一具有规范名称的对象是模块、函数和类,当然,在定义了函数或类或导入了模块之后,不能保证这个规范名称在任何命名空间中都有任何意义。这些名称还可以在创建对象后修改,因此它们可能并不总是特别值得信赖。

如果不递归遍历命名对象的树,就不可能实现你想做的事情;名称是对对象的单向引用。普通或普通的Python对象不包含对其名称的引用。想象一下,如果每个整数、每个字典、每个列表、每个布尔值都需要维护一个表示引用它的名称的字符串列表!这将是实现的噩梦,对程序员没有什么好处。

from __future__ import annotations
import inspect
import pandas as pd


# 변수 이름 가져오기
def getVariableName(variable: str) -> (str | Exception):
    callers_local_vars = inspect.currentframe().f_back.f_locals.items()

    df = pd.DataFrame(callers_local_vars)
    df.columns = ['함수명', '값']

    try:
        return df[(df['값'] == variable)].iloc[0]['함수명']
    except Exception as e:
        return e


test = 'Hello World!'

if __name__ == '__main__':
    print(getVariableName(test))

许多答案只返回一个变量名。但如果有多个变量具有相同的值,这就不能很好地工作。下面是Amr Sharaki的答案的一个变体,如果更多变量具有相同的值,则返回多个结果。

def getVariableNames(variable):
    results = []
    globalVariables=globals().copy()
    for globalVariable in globalVariables:
        if id(variable) == id(globalVariables[globalVariable]):
            results.append(globalVariable)
    return results

a = 1
b = 1
getVariableNames(a)
# ['a', 'b']

也许这很有用:

def Retriever(bar):
    return (list(globals().keys()))[list(map(lambda x: id(x), list(globals().values()))).index(id(bar))]

该函数遍历全局作用域的值的ID列表(可以编辑命名空间),根据其ID找到想要/需要的var或函数的索引,然后根据获得的索引从全局名称列表中返回名称。