一尘不染

Python-将变量名作为字符串获取

python

此线程讨论如何在Python中以字符串形式获取函数名称:如何在Python中以字符串 形式获取函数名称?

如何对变量执行相同操作?与函数相反,Python变量没有__name__属性。

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

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

我正在寻找一个功能/属性,例如retrieve_name

retrieve_name(foo) 

返回字符串 'foo'

更新:

由于人们在问我为什么要这样做,这里有一个例子。我想从此列表在Pandas中创建一个DataFrame,其中列名称 由实际字典的名称给出:

# List of dictionaries for my DataFrame
list_of_dicts = [n_jobs, users, queues, priorities]

阅读 1884

收藏
2020-02-13

共2个答案

一尘不染

安装

pip install python-varname

用法

在函数内部检索变量名

from varname import varname
def function():
    return varname()

func = function()
# func == 'func'

# available calls to retrieve
func = function(
    # ...
)

func = \
    function()

func = function \
    ()
# calls lead to failure of retrieving
func = [function()]

具有长参数列表的函数

def function(*args):
    return varname()

func = function(
    1, # I
    2, # have
    3, # a
    4, # long
    5, # argument
    6, # list
)

# func == 'var_0'

def function(*args):
    return varname(context = 20)

func = function(
    1, # I
    2, # have
    3, # a
    4, # long
    5, # argument
    6, # list
)

# func == 'func'

varname 来电被深深掩埋

def function():
    # I know that at which stack this will be called
    return varname(caller = 3)

def function1():
    return function()

def function2():
    return function1()

func = function2()
# func == 'func'

检索类对象的实例名称

class Klass:
    def __init__(self):
        self.id = varname()
    def copy(self):
        return varname()

k = Klass()
# k.id == 'k'

k2 = k.copy()
# k2 == 'k2'

varname调用被深埋在类中

class Klass:
    def __init__(self):
        self.id = self.some_internal()

    def some_internal(self):
        return varname(caller = 2)

    def copy(self):
        return self.copy_id()

    def copy_id(self):
        return self.copy_id_internal()

    def copy_id_internal(self):
        return varname(caller = 3)

k = Klass()
# k.id == 'k'

k2 = k.copy()
# k2 == 'k2'

如果无法检索名称

varname静态索引的起始位置是0将变量名称标记为失败。

func = [function()]
# func == ['var_0']
func = function \
    ()
# func == 'var_1'

局限性

  • 通话必须以所需格式书写
  • 必须事先估计上下文,尤其是对于带有长参数列表的函数
  • 你必须知道函数/类将在哪个堆栈中调用
  • 为了提高性能,因为涉及检查,所以更好地缓存名称
  • 不支持别名
def function():
  return varname()
func = function

x = func() # unable to detect

误报

def func(**kwargs):
    return varname()
x = func(
    y = func()
)
# x == 'y'

# to avoid this, you have to write the kwargs
# in the same line where the is called
x = func(y=func())
# x == 'x'
2020-02-13
一尘不染

Python中唯一具有规范名称的对象是模块,函数和类,并且在定义函数或类或导入模块后,当然不能保证此规范名称在任何命名空间中都具有任何含义。这些名称也可以在创建对象之后进行修改,因此它们可能并不总是特别值得信赖。

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

2020-02-13