1.描述装饰器的作用
python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新功能。
2.python函数装饰器每个步骤的详解
a.首先来理解python中的函数
def hi(name="helloworld"):return "hi " + nameprint("1:",hi())
# output: 'helloworld'# 我们甚至可以将一个函数赋值给一个变量,比如
greet = hi
# 我们这里没有在使用小括号,因为我们并不是在调用hi函数
# 而是在将它放在greet变量里头。我们尝试运行下这个print("2",greet())
# output: 'helloworld'
b.在函数中定义函数
def hi(name="yasoob"):print("now you are inside the hi() function")def greet():return "now you are in the greet() function"def welcome():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
c.从函数中返回函数
def hi(name="yasoob"):def greet():return "now you are in the greet() function"def welcome():return "now you are in the welcome() function"if name == "yasoob":return greetelse:return welcomea = hi() print(a) # outputs: <function greet at 0x7f2143c01500> # 上面清晰地展示了`a`现在指向到hi()函数中的greet()函数 # 现在试试这个print(a()) # outputs: now you are in the greet() function
d.将函数作为参数传给另一个函数
def hi():return "hi yasoob!"def doSomethingBeforeHi(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!
e.第一个装饰器[相当于将被装饰的函数即调用的函数作为参数传入到@写的函数里面]
def a_new_decorator(a_func):def wrapTheFunction():print("I am doing some boring work before executing a_func()")a_func()print("I am doing some boring work after executing a_func()")return wrapTheFunctiondef a_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()e中正是python中装饰器做的事情,它们封装一个函数,并且用这样或者那样的方式来修改它的行为。或许你正疑惑,我们并未使用@符号?那只是一个简短的方式来生成一个被装饰的函数,这里我们使用@来运行之前的代码:@a_new_decorator
def a_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)
f.在函数中嵌入装饰器[将函数myfunc1传参给logging_decorator]
from functools import wrapsdef logit(logfile='out.log'):def logging_decorator(func):@wraps(func)def wrapped_function(*args, **kwargs):log_string = func.__name__ + " was called"print("1",log_string)# 打开logfile,并写入内容with open(logfile, 'a') as opened_file:# 现在将日志打到指定的logfileopened_file.write(log_string + '\n')# return func(*args, **kwargs)return wrapped_functionreturn logging_decorator@logit()
def myfunc1():passmyfunc1()