这个主题讨论如何在Python中将函数的名称作为字符串获取:如何在Python中将 函数名称作为字符串获取?
如何为变量做同样的事情?(注意Python变量没有属性__name__,至少在Python中retrieve_name)
换句话说,如果我有一个变量,例如:
foo = dict()
foo['bar'] = 2
Run Code Online (Sandbox Code Playgroud)
我正在寻找一个函数/属性,例如'foo':
retrieve_name(foo)
Run Code Online (Sandbox Code Playgroud)
返回字符串 __name__
既然人们在问我为什么要这样做,这里就是一个例子.我想在此列表中在Pandas中创建一个DataFrame,其中列名 由实际字典的名称给出:
# List of dictionaries for my DataFrame
list_of_dicts = [n_jobs, users, queues, priorities]
Run Code Online (Sandbox Code Playgroud)
Aiv*_*erg 176
使用 Python 3.8 可以简单地使用f-string调试功能:
>>> foo = dict()
>>> f'{foo=}'.split('=')[0]
'foo'
Run Code Online (Sandbox Code Playgroud)
kin*_*all 97
Python中具有规范名称的唯一对象是模块,函数和类,当然,在定义函数或类或导入模块之后,无法保证此规范名称在任何命名空间中具有任何含义.创建对象后也可以修改这些名称,因此它们可能并不总是特别值得信赖.
如果没有递归地遍历命名对象树,你不可能做什么.名称是对象的单向引用.常见或花园种类的Python对象不包含对其名称的引用.想象一下,如果每个整数,每个字典,每个列表,每个布尔值都需要维护表示引用它的名称的字符串列表!这将是一个实现噩梦,对程序员几乎没有好处.
sco*_*001 72
即使变量值没有指向名称,您也可以访问每个已分配变量及其值的列表,所以我很惊讶只有一个人建议在那里循环查找您的var名称.
有人在回答中提到你可能需要遍历堆栈并检查每个人的locals和globals才能找到foo,但如果foo在你调用这个retrieve_name函数的范围内分配,你可以使用inspect's current frame来获取所有这些局部变量.我的解释可能有点过于冗长(也许我应该使用"foo"更少的单词),但这里的代码看起来如何(请注意,如果有多个变量分配给相同的值,你会获取这两个变量名称):
import inspect
x,y,z = 1,2,3
def retrieve_name(var):
callers_local_vars = inspect.currentframe().f_back.f_locals.items()
return [var_name for var_name, var_val in callers_local_vars if var_val is var]
print retrieve_name(y)
Run Code Online (Sandbox Code Playgroud)
Pan*_*ang 60
使用该python-varname包,您可以轻松检索变量的名称
https://github.com/pwwang/python-varname
由于v0.6.0,你的情况,你可以这样做:
from varname.helpers import Wrapper
foo = Wrapper(dict())
# foo.name == 'foo'
# foo.value == {}
foo.value['bar'] = 2
Run Code Online (Sandbox Code Playgroud)
对于列表理解部分,您可以执行以下操作:
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
Run Code Online (Sandbox Code Playgroud)
更新:07/08/2021
要获取数据框的名称,您可以使用argname2(从 v0.7.1 开始)编写自己的包装器:
>>> # argname is superseded by argname2
>>> from varname import argname2
>>> from pandas import DataFrame
>>>
>>> df1 = DataFrame(dict(a=[1]))
>>> df2 = DataFrame(dict(b=[1]))
>>>
>>> def handle_dfs(*dfs):
... names = argname2('*dfs')
... for name, df in zip(names, dfs):
... df.__dfname__ = name
...
... for df in dfs:
... print(f'name: {df.__dfname__}, value: {df}')
...
>>> handle_dfs(df1, df2)
name: df1, value: a
0 1
name: df2, value: b
0 1
Run Code Online (Sandbox Code Playgroud)
我是这个包的作者。如果您有任何问题,请告诉我,或者您可以在 Github 上提交问题。
jua*_*aza 25
在python3上,此函数将获取堆栈中最外层的名称:
import inspect
def retrieve_name(var):
"""
Gets the name of var. Does it from the out most frame inner-wards.
:param var: variable to get name from.
:return: string
"""
for fi in reversed(inspect.stack()):
names = [var_name for var_name, var_val in fi.frame.f_locals.items() if var_val is var]
if len(names) > 0:
return names[0]
Run Code Online (Sandbox Code Playgroud)
它在代码的任何地方都很有用.遍历反向堆栈寻找第一场比赛.
kor*_*nce 22
我不相信这是可能的.请考虑以下示例:
>>> a = []
>>> b = a
>>> id(a)
140031712435664
>>> id(b)
140031712435664
Run Code Online (Sandbox Code Playgroud)
在a与b指向同一个对象,但对象无法知道指向它哪些变量.
fdv*_*ges 13
def name(**variables):
return [x for x in variables]
Run Code Online (Sandbox Code Playgroud)
它的使用方式如下:
name(variable=variable)
Run Code Online (Sandbox Code Playgroud)
Ans*_*dey 10
>> my_var = 5
>> my_var_name = [ k for k,v in locals().items() if v == my_var][0]
>> my_var_name
'my_var'
Run Code Online (Sandbox Code Playgroud)
如果 myvar 指向另一个变量时出现错误,请尝试此操作(@mherzog 建议)-
>> my_var = 5
>> my_var_name = [ k for k,v in locals().items() if v is my_var][0]
>> my_var_name
'my_var'
Run Code Online (Sandbox Code Playgroud)
locals() - 返回一个包含当前作用域局部变量的字典。通过遍历这个字典,我们可以检查具有等于定义变量的值的键,只需提取键就会为我们提供字符串格式的变量文本。
来自(稍作更改后) https://www.tutorialspoint.com/How-to-get-a-variable-name-as-a-string-in-Python
小智 8
这是一种方法.我不建议任何重要的东西,因为它会很脆弱.但这是可以完成的.
创建一个使用该inspect模块查找调用它的源代码的函数.然后,您可以解析源代码以标识要检索的变量名称.例如,这是一个调用的函数autodict,它接受一个变量列表并返回一个字典映射变量名称到它们的值.例如:
x = 'foo'
y = 'bar'
d = autodict(x, y)
print d
Run Code Online (Sandbox Code Playgroud)
会给:
{'x': 'foo', 'y': 'bar'}
Run Code Online (Sandbox Code Playgroud)
检查源代码本身比搜索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
Run Code Online (Sandbox Code Playgroud)
该操作发生在with行中inspect.getouterframes,它返回调用的代码中的字符串autodict.
这种魔力的明显缺点是它对源代码的结构做出了假设.当然,如果它在解释器中运行,它根本不起作用.
我编写了包裹法术来稳健地执行这种魔术。你可以写:
from sorcery import dict_of
columns = dict_of(n_jobs, users, queues, priorities)
Run Code Online (Sandbox Code Playgroud)
并将其传递给数据框构造函数。等效于:
columns = dict(n_jobs=n_jobs, users=users, queues=queues, priorities=priorities)
Run Code Online (Sandbox Code Playgroud)
>>> locals()['foo']
{}
>>> globals()['foo']
{}
Run Code Online (Sandbox Code Playgroud)
如果要编写自己的函数,可以这样做,以便可以检查在本地变量中定义的变量,然后检查全局变量。如果未找到任何内容,则可以在id()上进行比较,以查看变量是否指向内存中的相同位置。
如果变量在类中,则可以使用className。dict .keys()或vars(self)来查看变量是否已定义。
此函数将打印变量名称及其值:
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))
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)***Input & Function call:*** my_var = 10 print_this(my_var) ***Output**:* my_var: 10
我有一个方法,虽然不是最有效的……但它有效!(并且它不涉及任何花哨的模块)。
基本上它会将您的变量 ID与globals() 变量 IDs 进行比较,然后返回匹配项的名称。
def getVariableName(variable, globalVariables=globals().copy()):
""" Get Variable Name as String by comparing its ID to globals() Variables' IDs
args:
variable(var): Variable to find name for (Obviously this variable has to exist)
kwargs:
globalVariables(dict): Copy of the globals() dict (Adding to Kwargs allows this function to work properly when imported from another .py)
"""
for globalVariable in globalVariables:
if id(variable) == id(globalVariables[globalVariable]): # If our Variable's ID matches this Global Variable's ID...
return globalVariable # Return its name from the Globals() dict
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
160065 次 |
| 最近记录: |