在使用C ++开发时,我使用这个非常有用的宏:
#define DD(a) std::cout << #a " = [ " << a << " ]" << std::endl;std::cout.flush();
你能帮我在python中实现同样的想法吗?我不知道如何使用python函数实现#a
...
答案 0 :(得分:7)
当@Andrea Spadaccini和@adirau指出时,无法将值可靠地映射回Python变量名称。您可以遍历所有名称空间,查找引用给定值的变量名称,但这会对系统产生影响,并且可能会返回错误的变量名称。
传递变量名称要容易得多:
import inspect
def pv(name):
frame,filename,line_number,function_name,lines,index=inspect.getouterframes(
inspect.currentframe())[1]
# print(frame,filename,line_number,function_name,lines,index)
val=eval(name,frame.f_globals,frame.f_locals)
print('{0}: {1}'.format(name, val))
a=5
pv('a')
的产率:
a: 5
答案 1 :(得分:6)
您可以检查堆栈跟踪并“解析”它。由于您知道函数的名称(在本例中为dd),因此很容易找到调用并提取变量的名称。
import inspect
import re
def dd(value):
calling_frame_record = inspect.stack()[1]
frame = inspect.getframeinfo(calling_frame_record[0])
m = re.search( "dd\((.+)\)", frame.code_context[0])
if m:
print "{0} = {1}".format(m.group(1), value)
def test():
a = 4
dd(a)
test()
输出
a = 4
答案 2 :(得分:3)
我认为这不可能做到。
您发布的调试宏有效,因为它在编译之前,预处理期间,当您知道变量名称时展开。就像你自己编写所有cout
一样。
Python没有预处理器(AFAIK),有外部工具做类似的事情(pyp和其他),但你不能用标准语言定义宏。
所以你应该在运行时做你的伎俩。好吧,在运行时你不知道变量的“名称”,因为变量只是对象的引用,当你调用在对象上调用它的方法时,而不是在“变量”上。可以有许多指向该对象的变量,该对象如何知道使用哪个变量来调用该方法?
答案 3 :(得分:3)
你不能在python中获得变量(well,object)的名字。但是你可以传递对象的名称来获取它的值(有点与你用宏做的相反)
>>> a=4
>>> locals()['a']
4
编辑:可能会找到详细解释here
答案 4 :(得分:3)
import sys
def DD(expr):
frame = sys._getframe(1)
print '%s = %s' % (expr, repr(eval(expr, frame.f_globals, frame.f_locals)))
GLOBAL_VAR = 10
def test():
local_var = 20
DD('GLOBAL_VAR + local_var')
>>> test()
GLOBAL_VAR + local_var = 30
答案 5 :(得分:2)
Rod解决方案非常实用。 它甚至可以扩展到处理许多变量。 但是你可以用更少的魔法来接近它:
def dd(**kwargs):
print ", ".join(str(k) + "=" + str(v) for k, v in kwargs.iteritems())
a = 1
dd(a=a,b=3)
输出:
a=1, b=3