美文网首页Python
python 闭包,装饰器

python 闭包,装饰器

作者: C_Z_Q_ | 来源:发表于2019-12-08 16:36 被阅读0次

1. 闭包

在函数内部再定义一个函数,并且内部函数用到了外部函数作用域里的变量(enclosing),那么将这个内部函数以及用到的外部函数内的变量一起称为闭包(Closure)
基本格式:

def 外部函数名():
  内部函数需要的变量
  def 内部函数名()
    引用外部的变量
  return 内部函数

  • 注意:
    函数的作用域关系在函数定义阶段就已经固定,与调用位置无关。
    无论函数在何处调用,都需要回到定义阶段去找对应的作用域关系。
    闭包中不要引用外部函数中任何循环变量或后续会发生变化的变量(延迟计算)

2. 装饰器

2.1 装饰器语法糖

@ 符号就是装饰器的语法糖
它放在一个函数开始定义的地方,它就像一顶帽子一样戴在这个函数的头上。和这个函数绑定在一起。在我们调用这个函数的时候,第一件事并不是执行这个函数,而是将这个函数做为参数传入它头顶上这顶帽子,这顶帽子我们称之为装饰函数装饰器

装饰器的使用方法很固定:
(1) 先定义一个装饰函数(帽子)(也可以用类、偏函数实现)
(2) 再定义你的业务函数、或者类(人)
(3) 最后把这顶帽子带在这个人头上

2.2 装饰器无参数

格式:

def 装饰器外部函数(func):      #func 就是被装饰函数  
    def装饰器内部函数(*args, **kwargs):   #装饰器内部函数是一个闭包,它使用了外部函数的变量func装饰函数的功能
        装饰器的功能
        return func(*args, **kwargs)   #执行被装饰函数并返回被装饰函数的返回值
    return 返回装饰器内部函数名      #注!返回装饰器内部函数名而不是装饰器内部函数

@装饰器外部函数名   #将被装饰函数传入装饰器,返回装饰器内部函数引用
def 被装饰函数(被装饰函数的参数):
    被装饰函数的功能
    return 被装饰函数的返回值

接收返回值 = 被装饰函数(被装饰函数的参数)    #执行函数,即执行装饰器内部函数,这个闭包使用的func变量指向被装饰函数体
print(接收返回值)   #打印一下接收的返回值

2.4 装饰器带参数

根据功能需求,在原来的装饰器外面再加一层函数
格式:

def 需求函数(需求函数参数):
    def 装饰器外部函数(func):
        def 装饰器内部函数(*args, **kwargs):
            装饰器的功能
            return func(*args, **kwargs)
        return 装饰器内部函数
    return 装饰器外部函数


@需求函数('需求函数参数')  # 等价于 被装饰函数 = 需求函数('需求函数参数')(被装饰函数) ,即先执行需求函数('需求函数参数'),返回装饰
                         #(接上一行的解释)器外部函数引用(真正的装饰器),再用装饰器外部函数装饰被装饰函数,返回装饰器内部函数

def 被装饰函数(被装饰函数的参数):
    被装饰函数的功能
    return 被装饰函数的返回值

接收返回值 = 被装饰函数(被装饰函数的参数)    #执行函数,即执行装饰器内部函数,这个闭包使用的func变量指向被装饰函数体
print(接收返回值)   #打印一下接收的返回值

2.5 使用@wraps

当打印被装饰函数函数名时,因为被装饰函数是在装饰器内部函数调用所以显示装饰器内部函数名,想打印被装饰函数名时可以使用functools模块的wraps装饰器解决这个问题
格式:

from functools import wraps
def 需求函数(需求函数参数):
    def 装饰器外部函数(func):
        @wraps(func)
        def 装饰器内部函数(*args, **kwargs):
            装饰器的功能
            return func(*args, **kwargs)
        return 装饰器内部函数
    return 装饰器外部函数


@需求函数('需求函数参数')  # 等价于 被装饰函数 = 需求函数('需求函数参数')(被装饰函数) ,即先执行需求函数('需求函数参数'),返回装饰
                         #(接上一行解释)器外部函数引用(真正的装饰器),再用装饰器外部函数装饰被装饰函数,返回装饰器内部函数

def 被装饰函数(被装饰函数的参数):
    被装饰函数的功能
    return 被装饰函数的返回值

接收返回值 = 被装饰函数(被装饰函数的参数)    #执行函数,即执行装饰器内部函数,这个闭包使用的func变量指向被装饰函数体
print(接收返回值)   #打印一下接收的返回值

2.6 多个装饰器装饰同一个函数

格式:

# 装饰器1
def 装饰器外部函数(func):      #func 就是被装饰函数  
    def装饰器内部函数(*args, **kwargs):   #装饰器内部函数是一个闭包,它使用了外部函数的变量func装饰函数的功能
        装饰器的功能
        return func(*args, **kwargs)   #执行被装饰函数并返回被装饰函数的返回值
    return 返回装饰器内部函数名      #注!返回装饰器内部函数名而不是装饰器内部函数


# 装饰器2
def 装饰器外部函数(func):      #func 就是被装饰函数  
    def装饰器内部函数(*args, **kwargs):   #装饰器内部函数是一个闭包,它使用了外部函数的变量func装饰函数的功能
        装饰器的功能
        return func(*args, **kwargs)   #执行被装饰函数并返回被装饰函数的返回值
    return 返回装饰器内部函数名      #注!返回装饰器内部函数名而不是装饰器内部函数



@装饰器1的外部函数名   #将被装饰函数传入装饰器,返回装饰器内部函数引用
@装饰器2的外部函数名   #将被装饰函数传入装饰器,返回装饰器内部函数引用
def 被装饰函数(被装饰函数的参数):
    被装饰函数的功能
    return 被装饰函数的返回值

接收返回值 = 被装饰函数(被装饰函数的参数)    #执行函数,即执行装饰器内部函数,这个闭包使用的func变量指向被装饰函数体
print(接收返回值)   #打印一下接收的返回值

小结:多个装饰器的顺序,包装时,是从下往上的,也就是被装饰函数头上,哪个离得近就先包装哪个

2.7 基于类实现的装饰器

基于类装饰器的实现,必须实现__call____init__两个内置函数。

2.7.1 不带参数的类装饰器
  • __init__:接收被装饰函数
  • __call__ :实现装饰逻辑
    格式:
class 类装饰器函数(object):
  def __init__(self, func):  #接收被装饰函数
    self.func = func
 
  def __call__(self, *args, **kwargs):   #实现装饰逻辑
    装饰器函数的功能
    return self.func(*args, **kwargs)
 
@类装饰器函数名
def 被装饰函数(被装饰函数的参数):
    被装饰函数的功能

被装饰函数(被装饰函数的参数) #执行函数
2.7.2 带参数的类装饰器

带参数和不带参数的类装饰器有很大的不同。

__init__:不再接收被装饰函数,而是接收传入参数。
__call__ :接收被装饰函数,实现装饰逻辑。

格式:

class 类装饰器(object):
  def __init__(self, level='类装饰器函数参数'):
    self.level = level
 
  def __call__(self, func): # 接受函数
    def 装饰器内部函数(*args, **kwargs):
      装饰器的功能
      func(*args, **kwargs)
    return 装饰器内部函数名     #返回函数
 
@类装饰器函数名(level='类装饰器函数参数')
def 被装饰函数(被装饰函数的参数):
    被装饰函数的功能

被装饰函数(被装饰函数的参数) #执行函数

相关文章

  • Python的自定义超时机制——装饰器的妙用

    装饰器 关于装饰器的入门,可以参考这篇文章:12步轻松搞定python装饰器简单来说,装饰器其实就是一个闭包(闭包...

  • Python装饰器-专题笔记

    学会装饰器,Python更进阶 函数作用域到闭包到装饰器讲解,及闭包和装饰器的运用。 [√] 慕课网Meshare...

  • [python] 装饰器学习

    很多python的代码都带有装饰器=。=现在不学以后也要学学一下装饰器 闭包 在学装饰器之前先看看python的闭...

  • Python 2 - 高级用法 - 装饰器

    Python 2 - 高级用法 - 装饰器 一谈到 装饰器,就离不开闭包 闭包 闭包就是能够读取其他函数内部变量的...

  • Python装饰器——初识

    上次讲了Python的闭包,今天来讲一下闭包的应用——装饰器 1. 装饰器是什么 什么叫装饰器?顾名思义,它是一个...

  • python装饰器

    装饰器简述 要理解装饰器需要知道Python高阶函数和python闭包,Python高阶函数可以接受函数作为参数,...

  • python之理解闭包和装饰器

    python之理解闭包和装饰器 1、闭包函数 1.1 python中函数都是对象 结果: 上面定义一个shut函数...

  • 2020-012 python闭包与装饰器

    python闭包与装饰器 闭包 函数和对其周围状态(lexical environment,词法环境)的引用捆绑在...

  • 让Python的装饰器不再难理解

    注意: 如果对闭包不了解的同学请移步到这里先,因为装饰器要通过闭包来实现 前言 刚开始学Python的时候,装饰器...

  • Python 装饰器的诞生过程

    Python中的装饰器是通过利用了函数特性的闭包实现的,所以在讲装饰器之前,我们需要先了解函数特性,以及闭包是怎么...

网友评论

    本文标题:python 闭包,装饰器

    本文链接:https://www.haomeiwen.com/subject/xlgugctx.html