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

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

当前回答

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

这是我从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》中得到的。我花了一段时间才弄清楚如何实现。

其他回答

在Python中,def和class关键字将特定的名称绑定到它们定义的对象(函数或类)。类似地,模块通过在文件系统中调用某个特定的名称来命名。在这三种情况下,都有一种明显的方法可以将“规范”名称分配给有问题的对象。

然而,对于其他类型的对象,这样的规范名称可能根本不存在。例如,考虑列表中的元素。列表中的元素不是单独命名的,在程序中引用它们的唯一方法完全可能是在包含它们的列表上使用列表索引。如果将这样一个对象列表传递到函数中,则不可能为值分配有意义的标识符。

Python不会将赋值对象左边的名称保存到赋值对象中,因为:

这需要在多个冲突的对象中找出哪个名称是“规范的”, 对于那些从未赋值给显式变量名的对象来说,这是没有意义的, 这样效率会非常低, 实际上没有其他现存的语言能做到这一点。

例如,使用lambda定义的函数将始终具有"name" <lambda>,而不是特定的函数名。

最好的方法是简单地要求调用者传入一个(可选的)名称列表。如果输入“…”,“…”'太麻烦了,你可以接受一个包含逗号分隔的名字列表的字符串(像namedtuple那样)。

这个函数将输出变量名及其值:

import inspect

def print_this(var):
    callers_local_vars = inspect.currentframe().f_back.f_locals.items()
    print(str([k for k, v in callers_local_vars if v is var][0])+': '+str(var))

***输入和函数调用:*** My_var = 10 print_this (my_var) * * *输出* *:* my_var: 10

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

问题出现的原因是您对术语、语义或两者都感到困惑。

"variables" don't belong in the same category as "functions". A "variable" is not a thing that takes up space in memory while the code is running. It is just a name that exists in your source code - so that when you're writing the code, you can explain which thing you're talking about. Python uses names in the source code to refer to (i.e., give a name to) values. (In many languages, a variable is more like a name for a specific location in memory where the value will be stored. But Python's names actually name the thing in question.)

In Python, a function is a value. (In some languages, this is not the case; although there are bytes of memory used to represent the actual executable code, it isn't a discrete chunk of memory that your program logic gets to interact with directly.) In Python, every value is an object, meaning that you can assign names to it freely, pass it as an argument, return it from a function, etc. (In many languages, this is not the case.) Objects in Python have attributes, which are the things you access using the . syntax. Functions in Python have a __name__ attribute, which is assigned when the function is created. Specifically, when a def statement is executed (in most languages, creation of a function works quite differently), the name that appears after def is used as a value for the __name__ attribute, and also, independently, as a variable name that will get the function object assigned to it.

但大多数对象都没有这样的属性。

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

That's the thing: you don't "have" the variable in the sense that you're thinking of. You have the object that is named by that variable. Anything else depends on the information incidentally being stored in some other object - such as the locals() of the enclosing function. But it would be better to store the information yourself. Instead of relying on a variable name to carry information for you, explicitly build the mapping between the string name you want to use for the object, and the object itself.

当从变量值中查找变量名时, 你可能有几个变量等于相同的值, 例如var1 = 'hello'和var2 = 'hello'。

我的解决方案:

def find_var_name(val):

    dict_list = []
    global_dict = dict(globals())

    for k, v in global_dict.items():
        dict_list.append([k, v])
   
    return [item[0] for item in dict_list if item[1] == val]

var1 = 'hello'
var2 = 'hello'
find_var_name('hello')

输出

['var1', 'var2']
>>> locals()['foo']
{}
>>> globals()['foo']
{}

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

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