Python装饰器

函数调用加括号和不加括号的区别

  • 不带括号的函数。调用的结果是返回一个函数对象,不需要等待该函数执行完成
  • 带括号的函数,调用的结果是返回一个值,返回return的值,如果没有return则返回一个None。必须要等待函数执行完成
    def foo():
      print("ffffff")
      return "aaa"
    #不带括号的函数。调用的结果是返回一个函数对象,不需要等待该函数执行完成
    print(foo)
    #带括号的函数,调用的结果是返回一个值,返回return的值,如果没有return则返回一个None。必须要等待函数执行完成
    print(foo())

装饰器

装饰器定义

  • 装饰器是Python的一种语法糖,本质是一个可调用的对象,其参数是一个被装饰的函数。装饰器可能会处理被装饰的函数并返回,或者将其替换成另一个函数或对象
  • 语法糖是什么呢?
    语法糖指的是计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用;可以使用这种语法增加程序的可读性,从而减少程序代码出错的可能。

装饰器条件:

  • 装饰器本质上是个可调用的函数,它的参数是一个函数对象(被装饰的函数)
  • 装饰器函数的定义写在被装饰的函数之前
  • 怎么使用装饰器呢?在被装饰的函数前一行写@装饰器函数名

装饰器例子

  • 1、写一个简单的例子,没有返回值,只打印一句“这是一个函数**”
  • 2、增加需求,记录下函数的执行日志,在代码中添加日志代码
  • 3、重新定义一个函数:专门处理日志,日志处理完之后再执行真正的业务代码
#未添加装饰器
def foo():
    print("this is a func, foo")  #执行foo函数体
    #print("foo is running")
#传入函数对象func
def log(func):
    print("{} is running".format(func))  #打印日志
    func() #调用func()

log(foo)

#加入装饰器实现上述功能
def log2(func):
    print("{} is running".format(func))
    return func

@log2   #装饰器-----#先执行装饰器函数(打印日志),返回func函数对象;
def foo2(): #调用函数
    print("this is a func, foo2")

foo2()

图片说明

装饰器何时执行

  • 装饰器在被装饰的函数定义之后立即执行(即Python加载模块的时候)
#定义一个列表
registry = []

#定义一个函数,传入一个参数(函数对象)
def register(func):
    print("register is ",func)
    #把函数对象存入regitry列表中
    registry.append(func)
    #返回一个函数对象
    return func

@register
def f1():
    print("f1")

@register
def f2():
    print("f2")

def f3():
    print("f3")

if __name__ == '__main__':
    print("running main()")
    print("regitry->",registry)
    f1()
    f2()
    f3()

打印结果:
图片说明

装饰器的两种用法

  • 原封不动返回被装饰函数(如上面例子所示)
  • 把被装饰函数替换成新函数
    • 大多数装饰器,通常内部会定义一个闭包结构的函数,将其返回替换被装饰函数,用于不修改原函数的基础上增加额外的功能

闭包函数

一般是在装饰器中使用的

闭包函数满足三个条件:

  • 在一个外函数中定义了一个内函数,
  • 内函数里运用了外函数的临时变量,
  • 并且外函数的返回值是内函数的引用,这样就构成了一个闭包
    #闭包函数——outer是外部函数,a和b都是外部函数的临时变量
    def outer(a):
      b=10
      #inner是内函数
      def inner():
          #在inner中用到了外函数的临时变量
          print(a+b)
      #outer外函数得到返回值是内函数的引用
      return inner

把被装饰函数修饰成一个新函数

def log2(func):
    def log(a,b):
        print("{} is running".format(func))
        func(a,b)
    return log

@log2
def foo2(a,b):
    print("this is a func, foo2")
    print(a+b)

foo2(1,2)
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务