你能把这个调试宏从C ++翻译成python吗?

时间:2011-03-31 16:49:21

标签: c++ python debugging logging macros

在使用C ++开发时,我使用这个非常有用的宏:

#define DD(a) std::cout << #a " = [ " << a << " ]" << std::endl;std::cout.flush();

你能帮我在python中实现同样的想法吗?我不知道如何使用python函数实现#a ...

6 个答案:

答案 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