Python 闭包及装饰器
闭包是指延伸了作用域的函数。
自由变量(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 闭包及装饰器的更多相关文章
- python 闭包和装饰器
python 闭包和装饰器 一.闭包闭包:外部函数FunOut()里面包含一个内部函数FunIn(),并且外部函数返回内部函数的对象FunIn,内部函数存在对外部函数的变量的引用.那么这个内部函数Fu ...
- python闭包与装饰器
转自小马哥: 闭包和装饰器充分体现了Python语法糖的优雅感觉. 在本文中,我们的实验要完成两个工作,一个是加法,一个是累计调用加法的次数,最普通的Python程序可以这么写: def valida ...
- 高逼格利器之Python闭包与装饰器
生活在魔都的小明,终于攒够了首付,在魔都郊区买了一套房子:有一天,小明踩了狗屎,中了一注彩票,得到了20w,小明很是欢喜,于是想干脆用这20万来装修房子吧(decoration): 整个装修过程,小明 ...
- Python—闭包和装饰器
闭包 定义:内部函数对外部函数变量的引用,则将该函数与用到的变量称为闭包. 闭包必须满足以下三个条件: 必须有一个内嵌函数. 内嵌函数必须引用外部函数中的变量. 外部函数返回值必须是内嵌函数的引用. ...
- Python 简明教程 --- 22,Python 闭包与装饰器
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 当你选择了一种语言,意味着你还选择了一组技术.一个社区. 目录 本节我们来介绍闭包与装饰器. 闭包与 ...
- Python闭包及装饰器
Python闭包 先看一个例子: def outer(x): def inner(y): return x+y return innder add = outer(8) print add(6) 我们 ...
- python闭包以及装饰器
通俗的定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).它只不过是个“内层”的函数,由一个名字(变量)来指代,而这个名字(变 ...
- python闭包和装饰器
本文目录: 1. 闭包的解析和用法 2. 函数式装饰器 3. 类装饰器 一.闭包 闭包是一种函数,从形式上来说是函数内部定义(嵌套)函数,实现函数的扩展.在开发过程中,考虑到兼容性和耦合度问题,如果想 ...
- python闭包和装饰器(转)
一.python闭包 1.内嵌函数 >>> def func1(): ... print ('func1 running...') ... def func2(): ... prin ...
- 详解Python闭包,装饰器及类装饰器
在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...
随机推荐
- 【Software Test】Introduction to Software Testing
Introduction to Software Testing 文章目录 Going to Learn --. Evolution of The Software Industry Errors, ...
- 【Oracle】 并行查询
所谓并行执行,是指能够将一个大型串行任务(任何DML,一般的DDL)物理的划分为叫多个小的部分,这些较小的部分可以同时得到处理.何时使用并行执行:1.必须有一个非常大的任务 2.必须有充足的资源(CP ...
- ctfhub技能树—web前置技能—http协议—Cookie
打开靶机环境 查看显示内容 根据提示,需要admin登录才能得到flag 题目介绍为Cookie欺骗.认证.伪造 介绍一下cookie和session 一.cookie: 在网站中,http请求是无状 ...
- oracle新增ID主键列,如何补全旧数据的ID值
1.创建SEQUENCE CREATE SEQUENCE MONKEY.TEST_ADD_IDCOL_ID CACHE 100; 2.新增表栏位 ALTER TABLE MONKEY.TEST_ADD ...
- C#使用OracleParameter操作数据库
public static int GetScalar(string sql,params OracleParameter [] OracleParms) { using (OracleConnect ...
- Django实现文件在本地的存储和读取
需求介绍:将图片存入本地的电脑文件夹中,将图片的路径保存到数据库,然后通过数据库的路径读取文件: 1.文件的存入: 前端文件: <form class="form-horizontal ...
- Mybatis plus通用字段自动填充的最佳实践总结
在进行持久层数据维护(新增或修改)的时候,我们通常需要记录一些非业务字段,比如:create_time.update_time.update_by.create_by等用来维护数据记录的创建时间.修改 ...
- 用动图讲解分布式 Raft
一.Raft 概述 Raft 算法是分布式系统开发首选的共识算法.比如现在流行 Etcd.Consul. 如果掌握了这个算法,就可以较容易地处理绝大部分场景的容错和一致性需求.比如分布式配置系统.分布 ...
- Intellij idea 报错:Error : java 不支持发行版本5
保证下面几个地方编译版本一致: 分两步: 第一步,进入Project Structure中设置Project JDK 以及Project Level ,高于JDK5版本 第二步,进入设置中将项目的JD ...
- WebSocket TCP HTTP
RFC 6455 - The WebSocket Protocol https://tools.ietf.org/html/rfc6455 1.5. Design Philosophy _This s ...