装饰器

       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笔记:装饰器的更多相关文章

  1. Python各式装饰器

    Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: ...

  2. Python札记 -- 装饰器补充

    本随笔是对Python札记 -- 装饰器的一些补充. 使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码: #!/usr/bin/env python def deco(func): def ...

  3. python基础——装饰器

    python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...

  4. 【转】详解Python的装饰器

    原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...

  5. 两个实用的Python的装饰器

    两个实用的Python的装饰器 超时函数 这个函数的作用在于可以给任意可能会hang住的函数添加超时功能,这个功能在编写外部API调用 .网络爬虫.数据库查询的时候特别有用 timeout装饰器的代码 ...

  6. python 基础——装饰器

    python 的装饰器,其实用到了以下几个语言特点: 1. 一切皆对象 2. 函数可以嵌套定义 3. 闭包,可以延长变量作用域 4. *args 和 **kwargs 可变参数 第1点,一切皆对象,包 ...

  7. 理解Python中的装饰器//这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档

    转自:http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html 这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档 ...

  8. python基础—装饰器

    python基础-装饰器 定义:一个函数,可以接受一个函数作为参数,对该函数进行一些包装,不改变函数的本身. def foo(): return 123 a=foo(); b=foo; print(a ...

  9. 详解Python的装饰器

    Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...

  10. 关于python的装饰器(初解)

    在python中,装饰器(decorator)是一个主要的函数,在工作中,有了装饰器简直如虎添翼,许多公司面试题也会考装饰器,而装饰器的意思又很难让人理解. python中,装饰器是一个帮函数动态增加 ...

随机推荐

  1. [小程序]微信小程序登陆并获取用户信息

    1.小程序js端调用框架登陆API,获取到一个临时code,拿着这个code去调用自己的服务端接口 2.在自己的服务器端,使用app_id app_secrect code可以获取到用户的openid ...

  2. glog的编译和使用

    glog是google提供的一个轻量级日志库,有chromium开发经验的人都会发现,它和base库中的日志库非常像,其实base库中的日志库比它更加轻量级.glog在日常开发中的使用非常广泛.这里介 ...

  3. 跟着ALEX 学python day5 模块

    文档内容学习于 http://www.cnblogs.com/xiaozhiqi/  模块 1.模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),本质就是.py结尾的pyt ...

  4. Spring服务发现和注册

  5. docker 中,修改了 mysql 配置,如何重启 mysql?

    直接重新启动容器: docker restart containerID/containerName

  6. StarUML 系列,静态图与动态图,用例图,类图

    大部分:   静态图部分,即静态不动的图 1.用例图, Use case diagram 1.展示系统核心功能及与其交互的用户ACTOR 表示:椭圆

  7. Android Adapter中获得LayoutInflater

    LayoutInflater li =(LayoutInflater)MyContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

  8. 怎么删掉xampp文件夹

    删掉xampp文件夹时,提示:操作无法完成,因为其中的文件夹或文件已在另一程序中打开 具体的解决方法: 菜单栏输入:服务 找到apachezt和mysqlzt,并禁用    -- 因为之前打开Zent ...

  9. NOIP 2009 Hankson 的趣味题

    洛谷 P1072 Hankson 的趣味题 洛谷传送门 JDOJ 1648: [NOIP2009]Hankson的趣味题 T2 JDOJ传送门 Description Hanks 博士是BT (Bio ...

  10. luoguP4008 [NOI2003]文本编辑器

    题意 splay维护即可 code: #include<bits/stdc++.h> using namespace std; const int maxn=2000010; int T, ...