我使用单个装饰器来完成两个独立的功能:一个具有装饰器参数的规范;没有它的另一个。
当未传递可选参数时,返回类型是一个函数(具体来说,是装饰器中的int[]
)。但是,当传递可选参数时,它按预期工作。
你能解释一下这里发生了什么吗?为什么它在这些情况下会有不同的行为?
inner_function
结果:
def cache_disk(cache_folder="./cache"):
def wrapper(f):
def inner_function(*args, **kwargs):
result = f(*args, **kwargs)
return result
return inner_function
return wrapper
@cache_disk
def func1(data):
return [d for d in data]
@cache_disk(cache_folder='./cache/')
def func2(data):
return [d for d in data]
data = [1,2,3]
print(func1(data))
print(func2(data))
答案 0 :(得分:3)
请注意:
@decorator # no arguments
def func(...):
...
相当于:
def func(...):
...
func = decorator(func) # one 'level' of calls
那:
@decorator(...): # arguments
def func(...):
...
相当于:
def func(...):
...
func = decorator(...)(func) # two 'levels' of calls
在第一种情况下,装饰器只有一个参数,func
本身。在第二种情况下,装饰器的参数是来自...
行的@
,它是装饰器返回的函数,用{调用{ {1}}作为论据。
在您的示例中,
func
装饰器@cache_disk
def func1(data):
...
获取单个可调用的参数(cache_disk
,后者变为func
)并返回args[0]
。然后当你打电话:
wrapper
print(func1(data))
获得一个参数(wrapper
,后者变为data
)并返回f
。
因此,您有三种选择:
inner_function
(注意括号)装饰func1
,不将任何参数传递给@cache_disk()
本身,将cache_disk
传递给func
; wrapper
的行为方式取决于它是否传递了一个可调用的参数或其他内容;或cache_disk
为无参数版本提供方便的别名,然后使用cache_disk.wrapper = cache_disk()
进行装饰。答案 1 :(得分:1)
如果你想要默认值,你需要调用函数,它返回一个装饰器:
@cache_disk()
def func1(data):
return [d for d in data]