此线程讨论如何在 Python 中将函数的名称作为字符串获取:如何获取函数名作为字符串?一个>
This thread discusses how to get the name of a function as a string in Python: How to get a function name as a string?
我怎样才能对变量做同样的事情?与函数相反,Python 变量没有 __name__
属性.
How can I do the same for a variable? As opposed to functions, Python variables do not have the __name__
attribute.
换句话说,如果我有一个变量,例如:
In other words, if I have a variable such as:
foo = dict()
foo['bar'] = 2
我正在寻找一个函数/属性,例如retrieve_name()
为了 从此列表中在 Pandas 中创建一个 DataFrame,其中列名由实际字典的名称给出:
I am looking for a function/attribute, e.g. retrieve_name()
in order to create a DataFrame in Pandas from this list, where the column names are given by the names of the actual dictionaries:
# List of dictionaries for my DataFrame
list_of_dicts = [n_jobs, users, queues, priorities]
columns = [retrieve_name(d) for d in list_of_dicts]
使用 python-varname
Wrapper 帮助程序>:
from varname.helpers import Wrapper
foo = Wrapper(dict())
# foo.name == 'foo'
# foo.value == {}
foo.value['bar'] = 2
对于列表理解部分,您可以这样做:
For list comprehension part, you can do:
n_jobs = Wrapper(<original_value>)
users = Wrapper(<original_value>)
queues = Wrapper(<original_value>)
priorities = Wrapper(<original_value>)
list_of_dicts = [n_jobs, users, queues, priorities]
columns = [d.name for d in list_of_dicts]
# ['n_jobs', 'users', 'queues', 'priorities']
# REMEMBER that you have to access the <original_value> by d.value
我是 python-varname
包的作者.如果您有任何问题,请告诉我,或者您可以在 Github 上提交问题.
I am the author of the python-varname
package. Please let me know if you have any questions or you can submit issues on Github.
是和否.
我们在运行时检索变量名,因此我们需要调用一个函数来使我们能够访问之前的帧以检索变量名.这就是我们需要一个 Wrapper
的原因.在该函数中,在运行时,我们正在解析前一帧中的源代码/AST 节点以获取确切的变量名称.
We are retrieving the variable names at runtime, so we need a function to be called to enable us to access the previous frames to retrieve the variable names. That's why we need a Wrapper
there. In that function, at runtime, we are parsing the source code/AST nodes in the previous frames to get the exact variable name.
但是,之前帧中的源代码/AST节点并不总是可用的,或者它们可能被其他环境修改(例如:pytest
的assert
语句).一个简单的例子是代码通过 exec()
运行.即使我们仍然能够从字节码中检索到一些信息,但它需要付出太多的努力,而且还容易出错.
However, the source code/AST nodes in the previous frames are not always available, or they could be modified by other environments (e.g: pytest
's assert
statement). One simple example is that the codes run via exec()
. Even though we are still able to retrieve some information from the bytecode, it needs too much effort and it is also error-prone.
首先,我们需要确定给定变量的帧.它并不总是简单的直接前一帧.例如,我们可能有另一个函数的包装器:
First of all, we need to identify which frame the variable is given. It's not always simply the direct previous frame. For example, we may have another wrapper for the function:
from varname import varname
def func():
return varname()
def wrapped():
return func()
x = wrapped()
在上面的例子中,我们必须跳过 wrapped
内的帧才能到达正确的帧 x = Wrapped()
以便我们能够定位 x代码>.
varname
的参数 frame
和 ignore
允许我们跳过其中一些中间帧.在 README 文件和包的 API 文档中查看更多详细信息.
In the above example, we have to skip the frame inside wrapped
to get to the right frame x = wrapped()
so that we are able to locate x
. The arguments frame
and ignore
of varname
allow us to skip some of these intermediate frames. See more details in the README file and the API docs of the package.
然后我们需要解析 AST 节点来定位变量被赋值(函数调用)的位置.这并不总是一个简单的任务.有时可能会有复杂的 AST 节点,例如 x = [wrapped()]
.我们需要通过遍历 AST 树来识别正确的赋值.
Then we need to parse the AST node to locate where the variable is assigned value (function call) to. It's not always just a simple assignment. Sometimes there could be complex AST nodes, for example, x = [wrapped()]
. We need to identify the correct assignment by traversing the AST tree.
一旦我们确定了分配节点,它就是可靠的.
Once we identify the assignment node, it is reliable.
varname
完全取决于 executing
包来查找节点.确保执行检测的节点是正确的(另请参见 this).
它部分适用于应用其他 AST 魔法的环境,包括 pytest、ipython、macropy、birdseye、reticulate with R 等.无论是执行还是 varname 都不能 100% 地适用于这些环境.
It partially works with environments where other AST magics apply, including pytest, ipython, macropy, birdseye, reticulate with R, etc. Neither executing nor varname is 100% working with those environments.
嗯,是的,又不是.
如果您的场景很简单,@juan Isaza 或 @scohe001 提供的代码可能足以让您处理在直接前一帧定义变量且 AST 节点是简单赋值的情况.您只需返回一帧并在那里检索信息.
If your scenario is simple, the code provided by @juan Isaza or @scohe001 probably is enough for you to work with the case where a variable is defined at the direct previous frame and the AST node is a simple assignment. You just need to go one frame back and retrieve the information there.
但是,如果场景变得复杂,或者我们需要采用不同的应用场景,你可能需要像 python-varname
,来处理它们.这些场景可能包括:
However, if the scenario becomes complicated, or we need to adopt different application scenarios, you probably need a package like python-varname
, to handle them. These scenarios may include to:
x = str(func())
f-string
怎么样?
就像@Aivar Paalberg 提供的答案一样.它绝对是快速和可靠的.但是,它不是在运行时,这意味着您必须在打印名称之前知道它是 foo
.但是使用 varname
,您不必知道该变量即将到来:
Like the answer provided by @Aivar Paalberg. It's definitely fast and reliable. However, it's not at runtime, meaning that you have to know it's foo
before you print the name out. But with varname
, you don't have to know that variable is coming:
from varname import varname
def func():
return varname()
# In external uses
x = func() # 'x'
y = func() # 'y'
python-varname
不仅能够从赋值中检测变量名,而且:
python-varname
is not only able to detect the variable name from an assignment, but also:
nameof
will
argname
nameof
will
argname
从其文档中了解更多信息.
Read more from its documentation.
但是,我想说的最后一句话是,尽量避免使用它.
However, the final word I want to say is that, try to avoid using it whenever you can.
因为您无法确保客户端代码将在源节点可用或 AST 节点可访问的环境中运行.当然,解析源代码、识别环境、检索 AST 节点并在需要时评估它们会耗费资源.
Because you can't make sure that the client code will run in an environment where the source node is available or AST node is accessible. And of course, it costs resources to parse the source code, identify the environment, retrieve the AST nodes and evaluate them when needed.
这篇关于获取变量名作为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!