defhi(name="yasoob"):
print("now you are inside the hi() function")defgreet():
return"now you are in the greet() function"defwelcome():
return"now you are in the welcome() function"print(greet())print(welcome())print("now you are back in the hi() function")hi()#output:now you are inside the hi() function# now you are in the greet() function# now you are in the welcome() function# now you are back in the hi() function# 上面展示了无论何时你调用hi(), greet()和welcome()将会同时被调用。# 然后greet()和welcome()函数在hi()函数之外是不能访问的,比如:greet()#outputs: NameError: name 'greet' is not defined
defhi(name="yasoob"):
defgreet():
return"now you are in the greet() function"defwelcome():
return"now you are in the welcome() function"ifname == "yasoob":
returngreetelse:
returnwelcomea = hi()print(a)#outputs: <function greet at 0x7f2143c01500>#上面清晰地展示了`a`现在指向到hi()函数中的greet()函数#现在试试这个print(a())#outputs: now you are in the greet() function
当我们写下 a = hi(),hi() 会被执行,而由于 name 参数默认是 yasoob,所以函数 greet 被返回了。如果我们把语句改为 a = hi(name = "ali"),那么 welcome 函数将被返回。我们还可以打印出 hi()(),这会输出 now you are in the greet() function。
将函数作为参数传给另一个函数
defhi():
return"hi yasoob!"defdoSomethingBeforeHi(func):
print("I am doing some boring work before executing hi()")print(func())doSomethingBeforeHi(hi)#outputs:I am doing some boring work before executing hi()# hi yasoob!
defa_new_decorator(a_func):
defwrapTheFunction():
print("I am doing some boring work before executing a_func()")a_func()print("I am doing some boring work after executing a_func()")returnwrapTheFunctiondefa_function_requiring_decoration():
print("I am the function which needs some decoration to remove my foul smell")a_function_requiring_decoration()#outputs: "I am the function which needs some decoration to remove my foul smell"a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)#now a_function_requiring_decoration is wrapped by wrapTheFunction()a_function_requiring_decoration()#outputs:I am doing some boring work before executing a_func()# I am the function which needs some decoration to remove my foul smell# I am doing some boring work after executing a_func()
@a_new_decoratordefa_function_requiring_decoration():
"""Hey you! Decorate me!"""print("I am the function which needs some decoration to ""remove my foul smell")a_function_requiring_decoration()#outputs: I am doing some boring work before executing a_func()# I am the function which needs some decoration to remove my foul smell# I am doing some boring work after executing a_func()#the @a_new_decorator is just a short way of saying:a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
fromfunctoolsimportwrapsdefa_new_decorator(a_func):
@wraps(a_func)defwrapTheFunction():
print("I am doing some boring work before executing a_func()")a_func()print("I am doing some boring work after executing a_func()")returnwrapTheFunction
@a_new_decoratordefa_function_requiring_decoration():
"""Hey yo! Decorate me!"""print("I am the function which needs some decoration to ""remove my foul smell")print(a_function_requiring_decoration.__name__)# Output: a_function_requiring_decoration
现在好多了。我们接下来学习装饰器的一些常用场景。
蓝本规范:
fromfunctoolsimportwrapsdefdecorator_name(f):
@wraps(f)defdecorated(*args, **kwargs):
ifnotcan_run:
return"Function will not run"returnf(*args, **kwargs)returndecorated
@decorator_namedeffunc():
return("Function is running")can_run = Trueprint(func())# Output: Function is runningcan_run = Falseprint(func())# Output: Function will not run