Python笔记:装饰器
装饰器
1、特点:装饰器的作用就是为已存在的对象添加额外的功能,特点在于不用改变原先的代码即可扩展功能;
2、使用:装饰器其实也是一个函数,加上@符号后放在另一个函数“头上”就实现了装饰的功能,执行被装饰的函数时,其实相当于func(*args, **kwargs) = decorator(func)(*args, **kwargs);
3、基本原理:在加载装饰器时,也就是加载到@符时,会运行一次装饰器(也就是被@后的函数),它的返回值会替代被装饰的函数地址,而被装饰的函数的地址以装饰器函数参数的形式传进了装饰器。如下示例中:加载到@decorator时,运行了一次decorator()函数,这时函数hello()把函数名(也就是函数地址hello)作为装饰器参数func传了进去,decorator()执行完后返回函数inner()的函数地址,这个函数地址替代了函数hello()的函数地址,当执行hello('Jom')时,就会执行替换后的函数,即inner('Jom'),然后就会去执行inner()函数内的内容。
简单装饰器示例:
def decorator(func):
print('hello python!') # 相当于给hello添加的额外功能
def inner(name):
print('hello, my friend') # 相当于给hello添加的额外功能
func(name) # func即为hello()函数 return inner @decorator # 装饰器用@表示,函数decorator()装饰函数hello()
def hello(name):
print('hello %s!' % name) hello('Jom') # 执行函数 # 输出--------------------------------------------------------------
# hello python!
# hello, my friend
# hello Jom!
装饰器传参示例:
def decorator_var(var1, var2):
print('decorator_var') # 装饰器的传参,就是在简单装饰器外面再套一层“壳子”
# 并且加载到装饰器的时候,会自动执行decorator_var和decorator两个函数
def decorator(func):
print('decorator') def inner(name):
print(var1, var2)
func(name) return inner return decorator @decorator_var('Python', '')
def hello(name):
print('hello %s!' % name) hello('Jom') # 输出--------------------------------------------------
# decorator_var
# decorator
# Python 36
# hello Jom!
4、安全防护:被装饰的函数的__name__属性(只测试了这个属性)会被修改为装饰器函数返回的函数名(虽然本质上已经不是在执行原函数了,因为它被装饰了,但是“表面上”我们代码还是执行的是这个函数,所以看起来就是原先的函数的属性被修改了,这样明显就是不安全的),但是为了防止这种不安全的行为,可以使用“from functools import wraps”来装饰器装饰器返回的函数。
from functools import wraps # 装饰器__name__属性防护
def decorator(func):
@wraps(func) # 这个装饰器可以防止被装饰的函数的__name__属性值被修改
def inner(*args, **kwargs): # 可以使用*args和**kwargs为“万能”的传参方式,当然这里也可以写成inner(a, b)
func(*args, **kwargs) return inner # 加载到这个装饰器时,相当于:test_func = decorator(test_func),即test_func = inner
# 如果没有对__name__的保护,加载装饰器后,如:函数test_func的__name__属性就会由“test_func”变为“inner”了
@decorator
def test_func(a, b):
print('sum of a+b: %s' % (a + b))
Python笔记:装饰器的更多相关文章
- Python各式装饰器
Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: ...
- Python札记 -- 装饰器补充
本随笔是对Python札记 -- 装饰器的一些补充. 使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码: #!/usr/bin/env python def deco(func): def ...
- python基础——装饰器
python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...
- 【转】详解Python的装饰器
原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...
- 两个实用的Python的装饰器
两个实用的Python的装饰器 超时函数 这个函数的作用在于可以给任意可能会hang住的函数添加超时功能,这个功能在编写外部API调用 .网络爬虫.数据库查询的时候特别有用 timeout装饰器的代码 ...
- python 基础——装饰器
python 的装饰器,其实用到了以下几个语言特点: 1. 一切皆对象 2. 函数可以嵌套定义 3. 闭包,可以延长变量作用域 4. *args 和 **kwargs 可变参数 第1点,一切皆对象,包 ...
- 理解Python中的装饰器//这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档
转自:http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html 这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档 ...
- python基础—装饰器
python基础-装饰器 定义:一个函数,可以接受一个函数作为参数,对该函数进行一些包装,不改变函数的本身. def foo(): return 123 a=foo(); b=foo; print(a ...
- 详解Python的装饰器
Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...
- 关于python的装饰器(初解)
在python中,装饰器(decorator)是一个主要的函数,在工作中,有了装饰器简直如虎添翼,许多公司面试题也会考装饰器,而装饰器的意思又很难让人理解. python中,装饰器是一个帮函数动态增加 ...
随机推荐
- JS高阶---作用域与作用域链
大纲: 主体: (1)概论 (2)层级 执行上下文层级为n+1原则 作用域层级也是n+1原则 验证: (3)函数作用域作用 隔离变量,不同作用域下,相同变量名不会有冲突 (4) .
- E10【选款式】I don't like that style
核心句型 I don't like that style. 我不喜欢那个款式 场景对话 A:Look at those shoes. They're really nice. 瞧那双鞋.可真漂亮 B: ...
- 面向对象程序设计(Java) 第4周学习指导及要求
2019面向对象程序设计(Java)第4周学习指导及要求(2019.9.17-2019.9. 23) 学习目标 掌握类与对象的基础概念,理解类与对象的关系: 掌握对象与对象变量的关系: 掌握预定义类 ...
- day32_8_14 并发编程三 线程的GIL
一.GIL 什么是GIL? GIL是一个全局排他锁,简单来说就是为了防止多线程并行操作的锁.这里有官方解释: In CPython, the global interpreter lock, or G ...
- plantUML 安装
plantUML 安装 资源 http://www.graphviz.org/ https://graphviz.gitlab.io/_pages/Download/windows/graphviz- ...
- 【Spring IoC】BeanFactory 和 ApplicationContext(五)
一.BeanFactory容器 BeanFactory 容器是一个最简单的容器,它主要的功能是为依赖注入 (DI) 提供支持,这个容器接口在 org.springframework.beans.fac ...
- 【使用篇二】SpringBoot整合mybatis(7)
说明:使用SpringBoot+Mybatis+Jsp实现简单的用户增删查改 #用户表 DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `) NO ...
- Linux下的SVN服务器搭建(八)
1. 通过yum命令安装svnserve yum -y install subversion #查看svn安装位置 rpm -ql subversion 2. 创建版本库目录(此仅为目录,为后面创建版 ...
- 接口规范、容错处理规则、aph备份数据规则
前话:前后解耦,前端开发环节使用APH,后台开发环节postman(可考虑为后台也做一个aph后台版) 1.api标准:标识符(ret:1为正常数据,0为接口报错),数据体(data:api的数据容器 ...
- ASP.NET Core Windows 环境配置
ASP.NET Core 是对 ASP.NET 有重大意义的一次重新设计.本章节我们将介绍 ASP.NET Core 中的一些新的概念和它们是如何帮助我们开发现代化的 Web 应用程序 尽管 ASP. ...