【发布时间】:2010-12-11 13:06:54
【问题描述】:
这是我们面对装饰器时遇到的第一个例子。但我无法意识到我到底想要什么。
一个名为 LOG 的简单装饰器。它应该像这样工作:
@LOG
def f(a, b=2, *c, **d):
pass
结果应该是这样的:
f(1, pippo=4, paperino='luca')
===== Enter f =====
a = 1
b = 2
pippo = 4
paperino = luca
===== Exit f =====
作为参数传递给函数的每个参数都显示其值。
我发现问题比我想象的要难,主要是因为您可以通过多种不同的方式将参数传递给函数(想想带有 *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
我认为这并不像我想象的那么容易,但奇怪的是我没有在 Google 上找到我想要的东西。
您能告诉我我的解决方案是否可行吗?或者您能针对我提出的问题提出更好的解决方案吗?
谢谢大家。
【问题讨论】:
-
有效吗?如果它有效,那么没关系。如果没有,那么你就有问题了。向我们询问有关该问题的具体问题。
-
是的,你是对的。实际上它似乎有效。但是正如我所写的,有许多复杂的方法可以将参数传递给 Python 函数:使用元组、字典、默认参数……实际上,即使它看起来有效,我不确定它是否是正确的实现,它可以在每个案例。
-
我自己也成为了它的牺牲品,这个函数,在你所描述的绝对一般的形式中,对于你继续开发你的应用程序是必要的吗?听起来日志记录机制本身已经吸引了你的注意力,而且我从经验中知道这可能是一个可怕的生产力杀手。
-
我完全同意你的看法。继续我的工作对我来说并不重要。由于它不是那么重要并且我无法解决问题,因此我将其移至待办事项列表的底部。但现在这是一种练习......我想知道是否有一个通用、优雅和简单的解决方案来解决我所描述的问题。
-
别担心,我的大脑也是这样工作的。而且我怀疑这个网站上还有很多其他人......
标签: python logging introspection decorator