在调试时自动输出变量名
来源:互联网 发布:买电脑配件 知乎 编辑:程序博客网 时间:2024/04/30 08:31
在Python中,最好的debug方式是什么?毫无疑问,是print,但是print有时候显得有点笨拙,比如考虑下面的代码:
我们通过print输出a的值,方便debug,但是如果你的代码里有十几个变量需要这样的方式来查看值,那你一定会搞不清谁对应谁,所以,我们还需要什么呢?毫无疑问,变量的名字!
最简单的方法是,在输出变量的同时,输出变量名,比如将“print a"改为"print 'a : ', a”。每一个都要这样写,是不是很不爽?有没有一种方法,可以自动侦测变量名?
有,当然有,实际上,Python代码中所有的信息在编译之后都会被存储起来,这样,你不仅能获得Python运行时的动态信息,而且还能获得Python代码中的静态信息,变量名不就是一静态信息么。只需要利用Python的frame对象和code对象,就能完成一切魔法。
下面在输出变量值时自动获取变量名的一种解决方案:
输出的结果为:
<a, 1>
<b, 2>
<c, 3>
<d, i am a>
当然,这种方法并不是万能的,因为在Python中,并不是所有的对象都会对应名字,因为Python有时可以通过位置引用对象,所以名字就不是必须的了,如果将函数g中最后一行改为print_name(a, b, c, A()),那么输出的结果就变为:
<b, 1>
<c, 2>
<A, 3>
<, i am a>
def f(value):
a = value
print a
f(3)
a = value
print a
f(3)
我们通过print输出a的值,方便debug,但是如果你的代码里有十几个变量需要这样的方式来查看值,那你一定会搞不清谁对应谁,所以,我们还需要什么呢?毫无疑问,变量的名字!
最简单的方法是,在输出变量的同时,输出变量名,比如将“print a"改为"print 'a : ', a”。每一个都要这样写,是不是很不爽?有没有一种方法,可以自动侦测变量名?
有,当然有,实际上,Python代码中所有的信息在编译之后都会被存储起来,这样,你不仅能获得Python运行时的动态信息,而且还能获得Python代码中的静态信息,变量名不就是一静态信息么。只需要利用Python的frame对象和code对象,就能完成一切魔法。
下面在输出变量值时自动获取变量名的一种解决方案:
import sys
import dis
import StringIO
def parse_bytecodes(bufvalue):
var_names = []
bytecodes = bufvalue.split(' ')
length = len(bytecodes)
var_count = 0
for i in range(length-1, -1, -1):
bytecode = bytecodes[i]
if var_count != 0:
var_names.append(bytecode.split()[-1][1:-1])
var_count -= 1
if '-->' in bytecode:
var_count = int(bytecode.split()[-1])
var_names.reverse()
return var_names
def print_name(*args):
#replace standard stdout with a StringIO object
buf = StringIO.StringIO()
old_stdout = sys.stdout
sys.stdout = buf
#call dis.disco to get bytecodes
f = sys._getframe(1)
dis.disco(f.f_code, f.f_lasti)
#restore standard stdout
sys.stdout = old_stdout
#process bytecode
var_names = parse_bytecodes(buf.getvalue())
buf.close()
#print var name and var value
for i, var_name in enumerate(var_names):
print '<%s, %s>' % (var_name, args[i])
class A(object):
def __init__(self):
pass
def __str__(self):
return 'i am a'
def g():
a = 1
b = 2
c = 3
d = A()
print_name(a, b, c, d)
g()
import dis
import StringIO
def parse_bytecodes(bufvalue):
var_names = []
bytecodes = bufvalue.split(' ')
length = len(bytecodes)
var_count = 0
for i in range(length-1, -1, -1):
bytecode = bytecodes[i]
if var_count != 0:
var_names.append(bytecode.split()[-1][1:-1])
var_count -= 1
if '-->' in bytecode:
var_count = int(bytecode.split()[-1])
var_names.reverse()
return var_names
def print_name(*args):
#replace standard stdout with a StringIO object
buf = StringIO.StringIO()
old_stdout = sys.stdout
sys.stdout = buf
#call dis.disco to get bytecodes
f = sys._getframe(1)
dis.disco(f.f_code, f.f_lasti)
#restore standard stdout
sys.stdout = old_stdout
#process bytecode
var_names = parse_bytecodes(buf.getvalue())
buf.close()
#print var name and var value
for i, var_name in enumerate(var_names):
print '<%s, %s>' % (var_name, args[i])
class A(object):
def __init__(self):
pass
def __str__(self):
return 'i am a'
def g():
a = 1
b = 2
c = 3
d = A()
print_name(a, b, c, d)
g()
输出的结果为:
<a, 1>
<b, 2>
<c, 3>
<d, i am a>
当然,这种方法并不是万能的,因为在Python中,并不是所有的对象都会对应名字,因为Python有时可以通过位置引用对象,所以名字就不是必须的了,如果将函数g中最后一行改为print_name(a, b, c, A()),那么输出的结果就变为:
<b, 1>
<c, 2>
<A, 3>
<, i am a>
- 在调试时自动输出变量名
- eclipse中编写代码时如何自动提示变量名?
- php调试JS输出变量
- 在输出的调试信息中统一加上模块名前缀
- 运算符在变量名
- shell的字符串和数字的转化(数字自动做字符串处理,变量名做字符串输出用单引号)
- Eclipse自动补全变量名
- eclipse怎样自动补全变量名
- c++如何自动生成变量名
- eclipse自动生成变量名快捷键
- php 变量循环命名 赋值 变量名输出 <三>
- MyEclipse调试的时候,鼠标悬浮在变量上自动变量值的方法
- 【按键精灵】标记、变量及调试输出
- 浏览器友好的变量调试输出函数
- vs2010调试C++变量控制台输出
- vs2010在输出窗口输出调试信息
- 拿到脚本中变量名,根据变量名名称反向输出
- 如何在函数中输出函数名
- PLEAC-Perl 教程 - Arrays (Perl进阶者极力推荐)
- Spindle3.0--终于等到了!Tapestry3.0的Eclipse PlugI
- Struts tags (2) ----Bean(1)
- Struts tags (3) ----Bean(2)
- PLEAC-Perl 教程 - Hash (Perl进阶者极力推荐)
- 在调试时自动输出变量名
- jise及模板下载
- 开发基于JBoss的J2EE应用
- JDBC与字符集总结
- 在虚拟主机环境下备份数据库并且导出到EXCEL
- jsp+tomcat的配置--写给那些因为配置问题而焦虑不堪的
- jsp: 解决rs.getString()取值写入HTML不换行问题
- 大家来秀一秀各自的Web开发工具
- jive 3.1.1 安装指南