装饰器 decorator
来源:互联网 发布:unity3d工程师笔试题 编辑:程序博客网 时间:2024/05/16 10:10
环境:
mac osx , python3.5
首先看例子
在前面的描述器与静态方法,类方法中:
对于例子
class B(object): @staticmethod def foo(): pass
上面定义的类方法,使用的是装饰器的语法,@ 符号被称为 语法糖(syntactic sugar)。
以上类实现的效果等同于:
class B(object): def foo(): pass foo = staticmethod(foo)
从形式上看,第一个定义中函数名出现的次数小于第二种定义,使用装饰器明显使得定义简单。以上也是装饰器的工作原理。
闭包
如果定义如下函数:
def make_printer(word): def inner(): print(word) return innerdoge = make_printer('such wow!')doge()#such wow!
在python中一切皆对象。包括函数:
def f(): passtype(f)#<class 'function'>isinstance(f, object)#Truef.a =40f.a#40
也就是说函数能被像对象那样传递使用,它们可以被赋值给变量,在函数中作为参数传递。函数可以创建函数-这也是闭包的创建。
闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,闭包是由函数和与其相关的引用环境组合而成的实体。(一个函数和它的环境变量合在一起,就构成了一个闭包(closure)。在Python中,所谓的闭包是一个包含有环境变量取值的函数对象。)
根据概念也就是inner()/doge() 函数与 word 变量构成闭包。
装饰器作为闭包
根据装饰器的工作原理,可以将上面的例子写成 装饰器+闭包 形式:
def make_printer(func): def inner(*arg, **kwargs): func(*arg, **kwargs) return inner@make_printerdef doge(word): print(word)doge("such wow!")#such wow!
也就是:
def make_printer(func): def inner(*arg, **kwargs): func(*arg, **kwargs) return innerdef doge(word): print(word)doge= make_printer(doge)doge("such wow!")#such wow!doge.__name__#inner
__name__ 以及 __doc__属性值不对。参考使用 functools 以及 wrapt 的使用。
计数
def count(wrapped): def inner(*wargs, **kwargs): inner.counter += 1 return wrapped(*args, **kwargs) inner.counter = 0 #如果不在函数调用前提前给函数对象添加属性就会出错 return inner@countdef doge(): pass
赋值的装饰器
def skip_if(conditional, message): def dec(wrapped): def inner(*args, **kwargs): if not conditional: # Execute the function as normal return wrapped(*args, **kwargs) else: # Skip the function, print the message print(message) return inner return dec@skip_if(True, 'Will not execute, because I hate doge')def doge(): print('very print')doge()# Will not execute, because I hate doge
上面的情况可能理解有些困难。可以先看如下的改写:
def skip_if(conditional, message): def dec(wrapped): def inner(*args, **kwargs): if conditional: # Execute the function as normal return wrapped(*args, **kwargs) else: # Skip the function, print the message print(message) return inner return dec#@skip_if(True, 'Will not execute, because I hate doge')def doge(): print('very print')doge = skip_if(True, 'Will not execute, because I hate doge')doge()
执行上面的程序,出线如下错误: ypeError: dec() takes exactly 1 argument (0 given)
也就是说dec要赋值。那么可以把上面装饰器的执行流程理解为:
首先将 True, 'Will not execute, because I hate doge'分别赋值给
conditional, message,然后把
doge 函数对象赋值给下一个函数的参数
wrapped `
参考文章
A guide to python decorators
https://www.codeschool.com/blog/2016/05/12/a-guide-to-python-decorators/
Python中的闭包
http://www.2cto.com/kf/201507/420734.html
- Decorator Pattern(装饰器)
- 装饰器(Decorator)模式
- Decorator装饰器
- 装饰器(Decorator)模式
- 装饰器(Decorator)模式
- 装饰器(Decorator)模式
- 装饰器模式(Decorator)
- 装饰器(Decorator)模式
- Decorator装饰器
- 装饰器-decorator
- Python Decorator(装饰器)
- 装饰器(Decorator)模式
- python decorator(装饰器)
- Python 装饰器/Decorator
- Python decorator(装饰器)
- 装饰器 decorator (python)
- 装饰器模式 decorator
- Python装饰器 Decorator
- Linux GIT 的使用方法详解
- 牛课网刷题--剑指offer(二维数组中的查找)
- 指针
- Intellij和SpringBoot,gradle构建Hello world!工程
- infragistics 实例化新行
- 装饰器 decorator
- IPC的6种方式
- Scala数据集合操作
- 哈夫曼树及其应用
- 什么是公有IP地址?什么是私有IP地址?及各自范围介绍
- 装箱、拆箱以及Math类
- ANDROID开发之SQLite详解
- __declspec(dllexport)和__declspec(dllimport)
- 【Linux c】读写pcie配置空间(安装lib库)