我试图了解装饰器,所以我想从最简单的情况开始,检查/修改函数的输出:
示例1:
def checkIsFriend(func):
def wrapper(arg):
friends = ['alan', 'brian', 'carol']
ret = arg # function not called
if ret in friends:
return 'hello {}, good to see you!'.format(ret)
else:
return 'Sorry {}, don\'t know you...'.format(ret)
return wrapper
@checkIsFriend
def greet(name):
return 'hi {}, good to see you!'.format(name)
print greet('alan')
print greet('simon')
# output:
# hello alan, good to see you!
# Sorry simon, don't know you...
示例2:
def reject_vowels(func):
def wrapper():
reject = 'aieou'
new_str = []
ret = func() # need to call the function
for char in ret:
if char in reject:
continue
new_str.append(char)
return ''.join(new_str)
return wrapper
@reject_vowels
def make_string():
return 'hello world, how are you?'
print make_string()
# output:
# hll wrld, hw r y?
令我困惑的是,在示例1中,未调用装饰函数(arg)的参数。
在示例2中,我需要调用该函数。
有人可以解释这些例子的流程吗?
答案 0 :(得分:1)
我的想法是wrapper
将替换装饰的函数; decorator语法是函数应用程序的缩写。
@checkIsFriend
def greet(name):
...
只是
的缩写def greet(name):
...
greet = checkIsFriend(greet)
知道,checkIsFriend
应定义为
def checkIsFriend(func):
def wrapper(arg):
friends = ['alan', 'brian', 'carol']
if arg in friends:
return func(arg)
else:
return 'Sorry {}, don\'t know you...'.format(arg)
return wrapper
此处,func
可能是您的greet
函数或任何其他函数。在包装器中,我们对func
一无所知,只是它需要一个参数并返回一个值。包装器是一个新函数,它使用与func
相同的参数,实际上只是检查该参数的值来决定是简单地调用func
还是返回不同的字符串。
如果我们为func
定义帮助程序替换,可能会更有意义:
def checkIsFriend(func):
friends = ['alan', 'brian', 'carol']
def donotgreet(arg):
return "Sorry {}, don't know you...".format(arg)
def wrapper(arg):
if arg in friends:
f = func
else:
f = donotgreet
return f(arg)
return wrapper
所有包装器确定是否将其参数传递给并调用原始函数或装饰器定义的默认函数,具体取决于它接收的参数。
答案 1 :(得分:0)
你发布的装饰者会做不同的事情。
greet
被一个新函数替换,其中一个参数arg
不使用greet
。事实上,如果您更改greet
的正文以获取其他内容,则结果将完全相同。这个新函数用它接收的参数做一些操作并返回结果;它所做的操作类似于装饰函数greet
,但它无论如何都与它无关,无论你正在装饰什么功能,它都是一样的。make_string
被一个没有调用make_string
的参数的新函数替换,对其输出执行某些操作并返回结果。在这种情况下,如果您修饰了不同的函数,结果会有所不同,因为新函数实际上是使用装饰器接收的函数。装饰器不要求你实际使用装饰函数(比如在函数中使用参数不需要你实际使用它)。他们只会用他们返回的值替换装饰的东西,它可以是任何。通常它是你可以调用并且与装饰函数做相关的东西,因为否则它通常不是很有用(例如,在例1中你可以只有一个常规函数wrapper
做了什么,但没有必要。