闭包是指延伸了作用域的函数。

自由变量(free variable) 指未在本地作用域中绑定的变量

函数装饰器用于在源码中标记函数, 以某种方式增强函数的行为。

装饰器实质,把被装饰的函数替换为新函数, 二者接收相同的参数,绑定了被装饰函数最为自由变量,返回被装饰函数本该返回的值,同时还会做些额外操作

装饰器的一个特性就是他们在被装饰的函数定义之后立即执行

实现一个简单的装饰器:

def decorate(func):
def inner(*args, **kwargs):
print("我是装饰器")
func(*args, **kwargs)
return inner

@decorate # 相当于 func = decorator(func(*args, **kwargs)) = inner(*args, **kwargs) 同时绑定了被装饰函数的引用作为自由变量
def func(*args, **kwargs):
pass

@decorate
class Test(*args, **kwargs): # 相当于 Test = decorate(Test(*args, **kwargs)) = inner(*args, **kwargs) 同时绑定了被装饰函数的引用作为自由变量
pass

print(func.__code__.co_freevars) # 查看自由变量
print(func.__code__.co_varnames) # 查看局部变量

 叠加装饰器:

def decorate1(func):
def inner1(*args, **kwargs):
print("装饰器1开始装饰")
func(*args, **kwargs)
print("装饰器1装饰结束")
return inner1 def decorate2(func):
def inner2(*args, **kwargs):
print("装饰器2开始装饰")
func(*args, **kwargs)
print("装饰器2装饰结束")
return inner2 @decorate1 # 相当于 func = decorate1(decorate2(func(*args, **kwargs))) = inner1(inner2)同时绑定了被装饰函数的引用作为自由变量
@decorate2
def func(*args, **kwargs):
pass

 参数化装饰器:

创建一个装饰器工厂函数,将参数传给它,返回一个装饰器, 再应用到被装饰的函数上

def register(active=True):
def decorate(func):
def inner(*args, **kwargs):
print('before')
func(*args, **kwargs)
if active:
print('another operation')
print('after')
return inner
return decorate

@register(True) # 相当于 func = decorate(func(*args, **kwargs)) = inner(*args, **args) 同时绑定了参数active以及被装饰函数的引用作为自由变量
def func(a=1):
print(a)

print(func.__code__.co_freevars)

 类实现装饰器

class Decorator:
def __init__(self, func):
self._func = func def __call__(self, *args, **kwargs):
print('__call__')
self._func(*args, **kwargs) @Decorator
def func(*args, **kwargs): # func = Decorator(func(*args, **kwargs)) = obj 同时绑定了被装饰函数的引用作为实例
pass func()

 参数化类装饰器 : 类作为装饰器工厂, 实例为装饰器, 参数保存再实例中,将实例作为装饰器应用到被装饰函数上

class Decorator:
def __init__(self, active):
self._active = active def __call__(self, func):
def wrapper(*args, **kwargs):
if self._active:
print("another operation")
func(*args, **kwargs)
return wrapper @Decorator(active=True)
def func(*args, **kwargs): # func = obj(func(*args, **kwargs)) = wrapper(*args, **kwargs) 同时绑定了参数active作为实例
pass func()

  

Python 闭包及装饰器的更多相关文章

  1. python 闭包和装饰器

    python 闭包和装饰器 一.闭包闭包:外部函数FunOut()里面包含一个内部函数FunIn(),并且外部函数返回内部函数的对象FunIn,内部函数存在对外部函数的变量的引用.那么这个内部函数Fu ...

  2. python闭包与装饰器

    转自小马哥: 闭包和装饰器充分体现了Python语法糖的优雅感觉. 在本文中,我们的实验要完成两个工作,一个是加法,一个是累计调用加法的次数,最普通的Python程序可以这么写: def valida ...

  3. 高逼格利器之Python闭包与装饰器

    生活在魔都的小明,终于攒够了首付,在魔都郊区买了一套房子:有一天,小明踩了狗屎,中了一注彩票,得到了20w,小明很是欢喜,于是想干脆用这20万来装修房子吧(decoration): 整个装修过程,小明 ...

  4. Python—闭包和装饰器

    闭包 定义:内部函数对外部函数变量的引用,则将该函数与用到的变量称为闭包. 闭包必须满足以下三个条件: 必须有一个内嵌函数. 内嵌函数必须引用外部函数中的变量. 外部函数返回值必须是内嵌函数的引用. ...

  5. Python 简明教程 --- 22,Python 闭包与装饰器

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 当你选择了一种语言,意味着你还选择了一组技术.一个社区. 目录 本节我们来介绍闭包与装饰器. 闭包与 ...

  6. Python闭包及装饰器

    Python闭包 先看一个例子: def outer(x): def inner(y): return x+y return innder add = outer(8) print add(6) 我们 ...

  7. python闭包以及装饰器

    通俗的定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).它只不过是个“内层”的函数,由一个名字(变量)来指代,而这个名字(变 ...

  8. python闭包和装饰器

    本文目录: 1. 闭包的解析和用法 2. 函数式装饰器 3. 类装饰器 一.闭包 闭包是一种函数,从形式上来说是函数内部定义(嵌套)函数,实现函数的扩展.在开发过程中,考虑到兼容性和耦合度问题,如果想 ...

  9. python闭包和装饰器(转)

    一.python闭包 1.内嵌函数 >>> def func1(): ... print ('func1 running...') ... def func2(): ... prin ...

  10. 详解Python闭包,装饰器及类装饰器

    在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...

随机推荐

  1. awk中的if ,else

    local pct="$(awk -v one="$1" -v two="$2" 'BEGIN{ if (two > 0) { printf & ...

  2. 【高级排序算法】1、归并排序法 - Merge Sort

    归并排序法 - Merge Sort 文章目录 归并排序法 - Merge Sort nlogn 比 n^2 快多少? 归并排序设计思想 时间.空间复杂度 归并排序图解 归并排序描述 归并排序小结 参 ...

  3. innodb是怎么刷新日志缓冲的

    当innodb把日志缓冲刷新到磁盘日志文件的时候,先会用一个mutex锁住缓冲区,刷新到所需要的位置,然后移动剩下的条目到缓冲区的前面,当mutex释放时,可能有超过一个事务已经准备好刷新其日志记录, ...

  4. ctfhub技能树—RCE—过滤cat

    打开靶机 查看页面信息 构造payload 127.0.0.1 || ls 题目提示过滤了cat,但我还是想试试 果然不行 网页访问没有结果,应该和上题一样被注释了,使用和同样的方法进行解题 利用命令 ...

  5. python无法连接mysql,有个小坑,需要注意一下!

    尝试用python链接mysql数据库,按照教程里链接了小半夜,就是没有链接上,找了各种文章,最后发现是版本的问题,我想使用的模块是MySQLdb,刚刚去他们的官网看了一下,最近一次更新是2014年, ...

  6. 入门OJ:最短路径树入门

    题目描述 n个城市用m条双向公路连接,使得任意两个城市都能直接或间接地连通.其中城市编号为1..n,公路编号为1..m.任意个两个城市间的货物运输会选择最短路径,把这n*(n-1)条最短路径的和记为S ...

  7. IP2723T中文规格书PDF

    IP2723T 是一款集成多种协议.用于 USB 输出端口的快充协议 IC.支持多种快充协议,包括 USBTypeC DFP,PD2.0/PD3.0/PPS,HVDCPQC4/QC4+/QC3.0/Q ...

  8. 20V,24V转5V,20V,24V转3.3V降压芯片,IC介绍

    常用的20V和24V转5V,3.3V的LDO稳压和DC-DC降压芯片: PW6206系列是一款高精度,高输入电压,低静态电流,高速,低压降线性稳压器具有高纹波抑制.输入电压高达40V,负载电流高达10 ...

  9. 下面给出一个child-parent的表格,要求挖掘其中的父子辈关系,给出祖孙辈关系的表格。

    package org.apache.hadoop.examples; import java.util.HashMap; import java.io.IOException; import jav ...

  10. 在HDFS中将文件从源路径移动到目的路径。

    import java.text.SimpleDateFormat; import java.util.Scanner; import org.apache.hadoop.fs.FSDataInput ...