Python 之 装饰器的写法
普通装饰器
1. 不带参数的普通装饰器
from functools import wraps def use_logging(func):
@wraps(func) # 使得装饰器函数和原函数有一样的原信息(docstring、__name__等),但为方便,下面的例子没有使用。
def wrapper(*args, **kw):
print args
print kw
return func(*args, **kw)
return wrapper @use_logging
def foo(x, n=1):
print x, n
print 'I am foo' foo(3)
foo(1, n=2)
输出如下:
# foo(3)
(3,)
{} # 因为foo(x, n=1)是在user_logging之后调用的,foo(3)时并未传其他参数,所以这里输出为空。
3 1
I am foo # foo(1, n=2)
(1,)
{'n': 2}
1 2
I am foo
2. 带参数的普通装饰器
def use_logging(level):
def decorator(func):
def wrapper(*args, **kw):
if level == 'warning':
print '%s is running' % func.__name__
return func(*args, **kw)
return wrapper
return decorator @use_logging(level='warning')
def foo(name='FOO'):
print 'I am %s' % name @use_logging(level='info')
def bar(name='BAR'):
print 'I am %s' % name foo()
bar()
输出:
# foo()
foo is running
I am FOO # bar()
I am BAR
装饰器类
类装饰器具有灵活度大、高内聚、封装性等优点。当使用 @ 形式将装饰器附加到函数上时,就会调用 __call__() 方法。
1. 不带参数的装饰器类
class FOO(object):
def __init__(self, func):
self._func = func def __call__(self, *args, **kw):
print args, kw
kw['x'] = 34
return self._func(*args, **kw)
@FOO
def bar(a, x=1):
print a, x
print 'I am bar' bar(3,x=7)
输出:
(3,) {'x': 7}
3 34
I am bar
2. 带参数的装饰器类
class FOO(object):
def __init__(self, level='debug'):
self._level = level def __call__(self, func):
def _call(*args, **kw):
print args, kw
if self._level == 'error':
kw['x'] = 34
return func(*args, **kw)
return _call
@FOO('error') # FOO()
def foo(a, x=1):
print a, x
print 'I am foo' @FOO('info')
def bar(a, x=1):
print a, x
print 'I am bar' foo(2)
bar(3,x=7)
输出:
# foo(2)
(2,) {}
2 34
I am foo # bar(d, x=7)
(3,) {'x': 7}
3 7
I am bar
另外一种带参数的装饰器类的写法如下:
class FOO(object):
def __init__(self, level):
self._level = level def __call__(self, func):
self._func = func
return self._call
def _call(self, *args, **kw):
print args, kw
if self._level == 'error':
kw['x'] = 34
return self._func(*args, **kw)
@FOO('error')
def foo(a, x=1):
print a, x
print 'I am foo' @FOO(level='info')
def bar(a, x=1):
print a, x
print 'I am bar' foo(2)
bar(3,x=7)
输出的结果如上面的一致,注意加粗的地方。
Python 之 装饰器的写法的更多相关文章
- 如何写一个Python万能装饰器,既可以装饰有参数的方法,也可以装饰无参数方法,或者有无返回值都可以装饰
Python中的装饰器,可以有参数,可以有返回值,那么如何能让这个装饰器既可以装饰没有参数没有返回值的方法,又可以装饰有返回值或者有参数的方法呢?有一种万能装饰器,代码如下: def decorate ...
- python基础——装饰器
python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...
- 【转】详解Python的装饰器
原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...
- 详解Python的装饰器
Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...
- python初级装饰器编写
最近项目太忙好久没有学习python了,今天更新一下吧~~ 1.什么是python装饰器: 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返 ...
- 【转】Python之装饰器
[转]Python之装饰器 本节内容 必要知识回顾 情景模拟 装饰器的概念及实现原理 回马枪(带参数的装饰器) 一. 必要知识回顾 在开始说装饰器之前,需要大家熟悉之前说过的相关知识点: 函数即“变量 ...
- 进阶Python:装饰器 全面详解
进阶Python:装饰器 前言 前段时间我发了一篇讲解Python调试工具PySnooper的文章,在那篇文章开始一部分我简单的介绍了一下装饰器,文章发出之后有几位同学说"终于了解装饰器的用 ...
- Python各式装饰器
Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: ...
- Python札记 -- 装饰器补充
本随笔是对Python札记 -- 装饰器的一些补充. 使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码: #!/usr/bin/env python def deco(func): def ...
随机推荐
- win7绕过开机密码攻略
访问windows机器,经常会因为忘记了开机密码而苦恼.当然你也可以选择重装,这样最简单粗暴.如果有重要数据保存在C盘之类的(个人严重推荐不要保存到C盘),那就不是重装能解决的问题了.2014年12月 ...
- Servlet---RequestDispatcher.include方法
为了实现代码重用,需要将某些代码和数据放在一个或多个Servlet中,以供其他Servlet使用,提供了RequestDispatcher.include方法,首先通过getServletContex ...
- jquery怎么获取radio选中的值
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- PHP character garbled
MySql 控制台查询时出现乱码 Database&Table 的字符集 于Mysql控制台显示的字符集不一样 右键单击mysql控制台边框 单击属性 查看当前代码页的字符集模式是否于数 ...
- 深入理解javascript--笔记
书写可维护的代码 1,最小全局变量 在js中不用声明变量就可以直接使用,因此注意不要没有声明就使用.(无意中创建的全局变量)比如使用任务链进行var声明.var a=b=12;正确写法为var ...
- WebAPI的Get和Post访问
/// <summary> /// MVC 调用webapi接口返回框架快捷按钮和一级菜单(Get) /// </summary> /// <param name=&qu ...
- psp记录个人项目花费时间
预估时间 120min 设计分析时间 30min 具体设计时间 ≍40min 编码时间 ≍1h 测试时间 10min 整理结论时间 10min 总结与探讨时间 5min
- IOS 网络请求
技术交流新QQ群:414971585 关于网络请求的重要性我想不用多说了吧.对于移动客户端来说,网络的重要性不言而喻.常见的网络请求有同步GET, 同步POST, 异步GET, 异步POST.今天来看 ...
- UVa 712 S树
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- Install Debian note
environment: already install xp,win7 and win8PE, left 87G space to install Debian, this space not fo ...