【发布时间】:2018-01-13 06:58:25
【问题描述】:
def tracer(func, enabled=True):
def wrap(*args, **kwargs):
if enabled:
print('Calling {}'.format(func))
return func(*args, **kwargs)
return wrap
@tracer(enabled=False)
def rotate_list(l):
return l[1:] + [l[0]]
我有点困惑为什么这不起作用,特别是这部分:@tracer(enabled=False)
我理解这里发生的是:
每当tracer 执行调用时,函数对象rotate_list 就会作为参数传递。
我认为这不起作用的原因是因为跟踪器(以及与此相关的任何包装器)只接受可调用对象,enabled=False 不是可调用对象,因此它不起作用。
但是错误消息并不能很好地说明这一点,所以我想知道为什么错误消息是:
TypeError: tracer() missing 1 required positional argument: 'func'
我猜括号内的参数首先被评估,这样没有可调用的对象被传递给跟踪器?
我想这可以通过使用类装饰器来解决,比如
class Trace:
def __init__(self, enabled=False):
print('Inside __init__')
self.enabled = enabled
那么tracer = Trace(enabled=True) 会起作用,但我想看看如何在不使用类的情况下解决这个问题。
============
编辑(解决方案): 不要介意这个,只需输入它以确保我理解解决方案。 因为在装饰器中放置一个参数使它像一个正常的函数一样工作。解决方案是让装饰器返回另一个可调用对象(这是实际的装饰器)。
喜欢:
@dec
def foo: pass 将变为 foo = dec(foo)
@dec(ARG)
def foo: pass 将变为 foo = dec(ARG)(foo)
解决方案是让dec 返回另一个可调用对象,它是实际的装饰器。例如,该函数将是 wrap
foo = dec(ARG)(foo) 将变为foo = wrap(foo),其中ARG 已传递给dec。
多谢你们!我喜欢函数式编程。
【问题讨论】:
标签: python class python-decorators