python学习之装饰器是什么?
学完python函数,接下来我们跟着猿人学python一起来看看什么是装饰器。
大家应该多多少少在其它地方有看过或是听过“装饰器”这个词。装饰器,顾名思义,就是用来装饰的,它装饰的是一个函数,保持被装饰函数的原有功能,再装饰上(添油加醋)一些其它功能,并返回带有新增功能的函数对象,所以装饰器本质上是一个返回函数对象的函数(确切的说,装饰器应该是可调用对象,除了函数,类也可以作为装饰器)。
Python的装饰器(decorator)是一个很棒的机制,也是熟练运用Python的必杀技之一。在编程过程中,我们经常遇到这样的场景:登录校验,权限校验,日志记录等,这些功能代码在各个环节都可能需要,但又十分雷同,通过装饰器来抽象、剥离这部分代码可以很好解决这类场景。
什么是装饰器?
要理解Python的装饰器,首先我们先理解一下Python的函数对象。我们知道,在Python里一切都是对象,函数也不例外,函数是第一类对象(first-class objects),它可以赋值给变量,也可以作为list的元素,还可以作为参数传递给其它函数。
函数可以被变量引用
定义一个简单的函数:
def say_hi(): print('Hi!') say_hi()# Output: Hi!
我们可以通过另外一个变量say_hi2来引用say_hi函数:
say_hi2 = say_hi print(say_hi2)# Output: <function say_hi at 0x7fed671c4378>say_hi2()# Output: Hi!
上面的语句中say_hi2 和 say_hi 指向了同样的函数定义,二者的执行结果也相同。
函数可以作为参数传递给其它函数
def say_more(say_hi_func): print('More') say_hi_func() say_more(say_hi)# Output:# More# Hi
在上面的例子中,我们把say_hi函数当做参数传递给say_more函数,say_hi 被变量 say_hi_func 引用。
函数可以定义在其它函数内部
def say_hi(): print('Hi!') def say_name(): print('Tom') say_name() say_hi()# Output:# Hi!# Tomsay_name() # 报错
上述代码中,我们在say_hi()函数内部定义了另外一个函数say_name()。say_name()只在say_hi函数内部可见(即,它的作用域在say_hi函数内部),在say_hi外包调用时就会出错。
函数可以返回其它函数的引用
def say_hi(): print('Hi!') def say_name(): print('Tom') return say_name say_name_func = say_hi()# 打印Hi!,并返回say_name函数对象# 并赋值给say_name_funcsay_name_func()# 打印 Tom
上面的例子,say_hi函数返回了其内部定义的函数say_name的引用。这样在say_hi函数外部也可以使用say_name函数了。
前面我们理解了函数,这有助于我们接下来弄明白装饰器。
装饰器(Decorator)
装饰器是可调用对象(callable objects),它用来修改函数或类。
可调用对象就是可以接受某些参数并返回某些对象的对象。Python里的函数和类都是可调用对象。
函数装饰器,就是接受函数作为参数,并对函数参数做一些包装,然后返回增加了包装的函数,即生成了一个新函数。
让我们看看下面这个例子:
def decorator_func(some_func): # define another wrapper function which modifies some_func def wrapper_func(): print("Wrapper function started") some_func() print("Wrapper function ended") return wrapper_func # Wrapper function add something to the passed function and decorator returns the wrapper function def say_hello(): print ("Hello") say_hello = decorator_func(say_hello) say_hello()# Output:# Wrapper function started# Hello# Wrapper function ended
上面例子中,decorator_func 就是定义的装饰器函数,它接受some_func作为参数。它定义了一个wrapper_func函数,该函数调用了some_func但也增加了一些自己的代码。
- 点赞
- 收藏
- 关注作者
评论(0)