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

自由变量(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. 关于 percona monitoring plugins插件报slave is stoped on ip地址

    思路:肯定是某个item触发了触发器 去看触发器,找到 slave is stoped,如下图 看到键是mysql.running-slave ,然后去定义key的文件中查看该键对应的脚本,修改脚本. ...

  2. CTFHub - Web(六)

    命令注入: 1.进入页面,测试127.0.0.1, 关键代码: <?php $res = FALSE; if (isset($_GET['ip']) && $_GET['ip'] ...

  3. 透过现象看本质:Java类动态加载和热替换

    摘要:本文主要介绍类加载器.自定义类加载器及类的加载和卸载等内容,并举例介绍了Java类的热替换. 最近,遇到了两个和Java类的加载和卸载相关的问题: 1) 是一道关于Java的判断题:一个类被首次 ...

  4. floating point

    记录浮点数的单精度和双精度(IEEE754) 1.单精度(float) ​ 1.定义:单精度占4字节/32位,其中1号位符号位,其次是8位阶码/指数(阶符+阶数),23位尾数(小数). 2.双精度(d ...

  5. 从ReentrantLock源码入手看锁的实现

    写这篇确实挺伤脑筋的,是按部就班一行一行读,但是我想这么写估计很多没有接触过的可能就劝退了,很容易出现的一种现象就是看了后面忘了前面,而且很容易看了一行代码就一层层往下钻,这样不仅容易打击看源码的积极 ...

  6. error: Failed dependencies: rpm安装包失败报错依赖包

    error: Failed dependencies: mysql-community-release conflicts with (installed) mysql57-community-rel ...

  7. (17)-Python3之--文件操作

    1.文件的操作流程 第一,建立文件对象. 第二,调用文件方法进行操作. 第三,不要忘了关闭文件.(文件不关闭的情况下,内容会放在缓存,虽然Python会在最后自动把内容读到磁盘,但为了以防万一,要养成 ...

  8. js中的事件委托(事件代理)详解

    本文转载:https://www.cnblogs.com/liugang-vip/p/5616484.html#!comments js中的事件冒泡.事件委托是js 中一些需要注意的小知识点,这里结合 ...

  9. (转载)微软数据挖掘算法:Microsoft 神经网络分析算法(10)

    前言 有段时间没有进行我们的微软数据挖掘算法系列了,最近手头有点忙,鉴于上一篇的神经网络分析算法原理篇后,本篇将是一个实操篇,当然前面我们总结了其它的微软一系列算法,为了方便大家阅读,我特地整理了一篇 ...

  10. vscode远程开发安装

    https://www.cnblogs.com/xiaoqi/p/vs-code-remote.html ============================= https://blog.csdn ...