Python调试技术之变量名称获取
郝伟 2021/03/29
这样的代码相信大家都很常用:
a, b = 10, 20 print('a=', a) print('b=', a)
其作用是在输出时显示变量a的名称,我们可否简化成:
a, b = 10, 20 show(a) show(b)
然后显示同样的内容呢?
以下代码定义了一个变量并进行调用输出:
s1 = pandas.DataFrame([1, 2, 3], list('abc')) show(s1.index)
输出:
s1.index = Index(['a', 'b', 'c'], dtype='object')
可见,show函数能够获得输入变量的名称,并自动输出,达到了我们预期的目标。
代码中实际上共提供了三种方法,只有最后一种最完善。
解释都放在代码中了,不再细表。
import matplotlib.pyplot as plt import pandas as pd import re import traceback import inspect pattren = re.compile(r'[\W+\w+]*?get_variable_name\((\w+)\)') __get_variable_name__ = [] def get_variable_name(x): global __get_variable_name__ if not __get_variable_name__: __get_variable_name__ = pattren.findall(traceback.extract_stack(limit=2)[0][3]) return __get_variable_name__.pop(0) def retrieve_variable_name(var): """ 获得变量var的名称,这个名称是最开始定义时的名称。 获取原理是利用变量存储栈。 如果获取失败则返回长度为0的字符串。 :参数 var: 待获得名称的变量。 :返回类型: 字符串 """ 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] return '' def test0(): print('hello') plt.plot([1,2, 3], [4,5,6]) plt.plot(range(100), [i * i for i in range(100)]) plt.plot(1,2) plt.show() # 反射有四个方法:hasattr、getattr、setattr、delattr,比较常用的是前两种,一般会结合起来用。 def show(obj1, prop_name): # print('name:', get_variable_name(obj1)) # print('name:', retrieve_variable_name(obj1)) title=retrieve_variable_name(obj1)+'.'+prop_name+':' if hasattr(obj1, prop_name): v = getattr(obj1, prop_name) print(title, v) else: print(title) s1 = pd.DataFrame([1, 2, 3], list('abc')) print(s1.index) print(getattr(s1, 'index')) show(s1, 'index') # print('s1:', get_variable_name(s1)) print('sig:', inspect.signature(retrieve_variable_name)) print('1:', retrieve_variable_name(s1.index)) #print('2:', retrieve_variable_name(s1.index)) # ★★★★ 真正可用的代码 ★★★★ # 参考: http://blog.csdn.net/chunyexiyu def retrieve_name_ex(var): ''' 实现的原理是利用inspect获得函数的源代码,从而取得变量的字符串。 ''' stacks = inspect.stack() try: code = stacks[2].code_context[0] # 获得调用行的代码 callFunc = stacks[1].function # 获得调用的函数名 # 获得函数中起始索引位置,以取得变量名称的字符串 startIndex = code.index("(", code.index(callFunc) + len(callFunc)) + 1 endIndex = code.index(")", startIndex) name=code[startIndex:endIndex].strip() # 获得变量名称 return name except: return "" def show(var): print(retrieve_name_ex(var), '=', var) outputVar(s1.index)
通过本文,我们可以掌握获得一个变量的完整名称的几种方法。在此基础之上,我们可以利用 inspect 库,实现对代码进行过程中的全面监视,从而可以实现更多更强大的能力。
Python获取变量名称,https://blog.csdn.net/chunyexiyu/article/details/84879295
Python 中的反射操作,https://zhuanlan.zhihu.com/p/99150129