理解装饰器:return type is a function when argument not specified
Understanding decorators: return type is a function when argument not specified
我正在为两个独立的函数使用一个装饰器:一个带有装饰器参数规范;另一个没有它。
当不传递可选参数时,return类型是一个函数(具体来说,装饰器中的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))
结果:
<function inner_function at 0x7f1f283d5c08>
[1, 2, 3]
如果你想要默认值,你需要调用函数,returns装饰器:
@cache_disk()
def func1(data):
return [d for d in data]
注意:
@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
本身。在第二种情况下,装饰器的参数是来自 @
行的 ...
,它是 装饰器返回的函数 用 func
作为参数。
在你的例子中,
@cache_disk
def func1(data):
...
装饰器 cache_disk
得到一个单一的、可调用的参数(func
,变成 args[0]
)和 returns wrapper
。然后当你打电话时:
print(func1(data))
wrapper
得到一个参数(data
,变成 f
)和 returns inner_function
.
因此,您有以下三种选择:
- 用
@cache_disk()
装饰 func1
(注意括号),不向 cache_disk
本身传递任何参数,而 func
向 wrapper
; 传递任何参数
- 改变
cache_disk
以根据传递的是单个可调用参数还是其他参数而表现不同;或
- 正如 @o11c 在评论中指出的那样,使用例如
cache_disk.wrapper = cache_disk()
为无参数版本提供一个方便的别名,然后用 @cache_disk.wrapper
. 修饰
我正在为两个独立的函数使用一个装饰器:一个带有装饰器参数规范;另一个没有它。
当不传递可选参数时,return类型是一个函数(具体来说,装饰器中的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))
结果:
<function inner_function at 0x7f1f283d5c08>
[1, 2, 3]
如果你想要默认值,你需要调用函数,returns装饰器:
@cache_disk()
def func1(data):
return [d for d in data]
注意:
@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
本身。在第二种情况下,装饰器的参数是来自 @
行的 ...
,它是 装饰器返回的函数 用 func
作为参数。
在你的例子中,
@cache_disk
def func1(data):
...
装饰器 cache_disk
得到一个单一的、可调用的参数(func
,变成 args[0]
)和 returns wrapper
。然后当你打电话时:
print(func1(data))
wrapper
得到一个参数(data
,变成 f
)和 returns inner_function
.
因此,您有以下三种选择:
- 用
@cache_disk()
装饰func1
(注意括号),不向cache_disk
本身传递任何参数,而func
向wrapper
; 传递任何参数
- 改变
cache_disk
以根据传递的是单个可调用参数还是其他参数而表现不同;或 - 正如 @o11c 在评论中指出的那样,使用例如
cache_disk.wrapper = cache_disk()
为无参数版本提供一个方便的别名,然后用@cache_disk.wrapper
. 修饰