我已经阅读 了如何将函数名作为字符串获取? .
我怎样才能对变量做同样的事情?与函数相反,Python 变量没有 __name__
属性。
换句话说,如果我有一个变量,例如:
foo = dict()
foo['bar'] = 2
我正在寻找一个函数/属性,例如 retrieve_name()
以便 从此列表中在 Pandas 中创建一个 DataFrame ,其中 列名 由实际字典的名称给出:
# List of dictionaries for my DataFrame
list_of_dicts = [n_jobs, users, queues, priorities]
columns = [retrieve_name(d) for d in list_of_dicts]
原文由 Amelio Vazquez-Reina 发布,翻译遵循 CC BY-SA 4.0 许可协议
TL;博士
使用来自
python-varname
的Wrapper
助手:对于列表理解部分,您可以执行以下操作:
我是
python-varname
包的作者。如果您有任何问题,请告诉我,或者您可以在 Github 上提交问题。长答案
甚至可能吗?
是和否。
我们在运行时检索变量名称,因此我们需要调用一个函数以使我们能够访问先前的帧以检索变量名称。这就是为什么我们需要一个
Wrapper
那里。在该函数中,在运行时,我们正在解析前一帧中的源代码/AST 节点以获取确切的变量名称。但是,之前帧中的源代码/AST 节点并不总是可用,或者它们可能被其他环境修改(例如:
pytest
的assert
语句)。一个简单的例子是代码通过exec()
运行。即使我们仍然能够从字节码中检索一些信息,但它需要太多的努力,而且也容易出错。怎么做?
首先,我们需要确定给定变量的帧。它并不总是简单的直接前一帧。例如,我们可能有另一个函数的包装器:
在上面的示例中,我们必须跳过
wrapped
中的帧以到达正确的帧x = wrapped()
以便我们能够定位x
。参数frame
和ignore
的varname
允许我们跳过这些中间帧。在 README 文件和包的 API 文档中查看更多详细信息。然后我们需要解析 AST 节点来定位变量被赋值(函数调用)的位置。这并不总是一个简单的任务。有时可能会有复杂的 AST 节点,例如
x = [wrapped()]
。我们需要通过遍历 AST 树来识别正确的分配。它有多可靠?
一旦我们确定了分配节点,它就是可靠的。
varname
都是依赖executing
包来寻找节点。确保执行检测的节点是正确的(另请参见 this )。它部分适用于应用其他 AST 魔法的环境,包括 pytest、ipython、macropy、birdseye、reticulate with R 等。无论是执行还是 varname 都不能 100% 地适用于这些环境。
我们需要一个包来做吗?
嗯,是的,不是的,再一次。
如果您的场景很简单,那么@juan Isaza 或@scohe001 提供的代码可能足以让您处理在直接前一帧中定义变量并且AST 节点是简单赋值的情况。您只需要返回一帧并在那里检索信息。
但是,如果场景变得复杂,或者我们需要采用不同的应用场景,你可能需要像
python-varname
这样的包来处理它们。这些场景可能包括:x = str(func())
f-string
怎么样?就像@Aivar Paalberg 提供的答案一样。它绝对是快速和可靠的。但是,它不是在运行时,这意味着您必须在打印名称之前知道它是
foo
。但是使用varname
,您不必知道变量即将到来:最后
python-varname
不仅能够从赋值中检测变量名,而且:nameof
will
argname
获取传递给函数的参数名称/源从其文档中阅读更多内容。
但是,我想说的最后一句话是, 尽可能避免使用它。
因为您无法确保客户端代码将在源节点可用或 AST 节点可访问的环境中运行。当然,解析源代码、识别环境、检索 AST 节点并在需要时评估它们会耗费资源。