使用装饰器进行Python日志记录

Luc*_*uca 25 python logging introspection decorator

这是我们面对装饰时遇到的第一个例子.但是我无法意识到我到底想要什么.

一个名为LOG的简单装饰器.它应该像这样工作:

@LOG
def f(a, b=2, *c, **d):
    pass
Run Code Online (Sandbox Code Playgroud)

结果应该是这样的:

f(1, pippo=4, paperino='luca')
===== Enter f =====
a = 1
b = 2
pippo = 4
paperino = luca
===== Exit f =====
Run Code Online (Sandbox Code Playgroud)

将作为参数传递给函数的每个参数显示为其值.

我发现问题比我想象的更难,主要是因为你可以通过许多不同的方式将参数传递给函数(想想带有*c的元组或带有**d的字典).

我试过一个解决方案,但我不确定它是否正确.它有点像这样:

def LOG(fn):
    import inspect
    varList, _, _, default = inspect.getargspec(fn)
    d = {}
    if default is not None:
        d = dict((varList[-len(default):][i], v) for i, v in enumerate(default))
    def f(*argt, **argd):
        print ('Enter %s' % fn).center(100, '=')
        d.update(dict((varList[i], v) for i, v in enumerate(argt)))
        d.update(argd)
        for c in d.iteritems():
            print '%s = %s' % c
        ret = fn(*argt, **argd)
        print 'return: %s' % ret
        print ('Exit %s' % fn).center(100, '=')
        return ret
    return f
Run Code Online (Sandbox Code Playgroud)

我认为这并不像我预期的那么容易,但奇怪的是我没有在Google上找到我想要的东西.

你能告诉我我的解决方案是否合适?或者你能为我提出的问题提出更好的解决方案吗?

谢谢大家.

Joc*_*zel 5

我注意到的唯一事实是dict((varList[i], v) for i, v in enumerate(argt))你实际使用过两次的构造dict(zip(varList,argt)).

除此之外,我只有元批评:以上都不属于日志文件.

而不是通过日志来

  • 看看是否使用正确的args使用断言和调试器调用函数.
  • 看看函数是否返回了你编写单元测试的正确结果.

  • 感谢您提供有用的zip功能.我认为你对元批评是正确的.我在远程计算机上开发,我不能使用调试器.因此,这种日志记录机制应该是一种简单的调试方式. (2认同)