普通装饰器

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 之 装饰器的写法的更多相关文章

  1. 如何写一个Python万能装饰器,既可以装饰有参数的方法,也可以装饰无参数方法,或者有无返回值都可以装饰

    Python中的装饰器,可以有参数,可以有返回值,那么如何能让这个装饰器既可以装饰没有参数没有返回值的方法,又可以装饰有返回值或者有参数的方法呢?有一种万能装饰器,代码如下: def decorate ...

  2. python基础——装饰器

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

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

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

  4. 详解Python的装饰器

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

  5. python初级装饰器编写

    最近项目太忙好久没有学习python了,今天更新一下吧~~ 1.什么是python装饰器: 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返 ...

  6. 【转】Python之装饰器

    [转]Python之装饰器 本节内容 必要知识回顾 情景模拟 装饰器的概念及实现原理 回马枪(带参数的装饰器) 一. 必要知识回顾 在开始说装饰器之前,需要大家熟悉之前说过的相关知识点: 函数即“变量 ...

  7. 进阶Python:装饰器 全面详解

    进阶Python:装饰器 前言 前段时间我发了一篇讲解Python调试工具PySnooper的文章,在那篇文章开始一部分我简单的介绍了一下装饰器,文章发出之后有几位同学说"终于了解装饰器的用 ...

  8. Python各式装饰器

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

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

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

随机推荐

  1. Logistic回归分类算法原理分析与代码实现

    前言 本文将介绍机器学习分类算法中的Logistic回归分类算法并给出伪代码,Python代码实现. (说明:从本文开始,将接触到最优化算法相关的学习.旨在将这些最优化的算法用于训练出一个非线性的函数 ...

  2. mysqlbinlog 参数及用法说明

    mysqlbinlog用法说明 服务器生成的二进制日志文件写成二进制格式.要想检查这些文本格式的文件,应使用mysqlbinlog实用工具.应这样调用mysqlbinlog:shell> mys ...

  3. find和grep的区别

    find命令:在系统当中搜索符合条件的文件名,如果需要匹配,使用通配符匹配,通配符是完全匹配. grep命令:在文件当中搜索符合条件的字符串,如果需要匹配,使用正侧表达式匹配 正侧表达式是包含匹配.

  4. JSP代码加固

    String id = request.getParameter("id"); String id = id.replace("'","") ...

  5. objdump 分析

    objdump -H 显示如下: 一般常用的是 objdump -x 显示文件头信息 objdump -d 反汇编代码段代码 objdump -D 反汇编所有代码 用法:objdump <选项& ...

  6. C语言中内存的申请函数

    C语言跟内存申请相关的函数主要有 alloca,calloc,malloc,free,realloc,sbrk等. alloca是向栈申请内存,因此无需释放. malloc分配的内存是位于堆中的,并且 ...

  7. Unix系统小知识(转)

    Unix操作系统的小知识 2.VI添加行号/翻页/清屏 .在对话模式时(即输完Esc再输入: ),输入“:set number”可以将编辑的文本加上行号.跟玩俄罗斯方块一样方便的上下左右移动箭头的快捷 ...

  8. nagios监控系统安装及配置

    Nagios通常由一个主程序(Nagios).一个插件程序(Nagios-plugins)和四个可选的ADDON(NRPE.NSCA.NSClient++和NDOUtils)组成.Ngios的监控工作 ...

  9. MongoDB学习笔记八:复制

    [主从复制]最基本的复制方式就是建立一个主节点和一个或多个从节点,每个从节点要知道主节点的地址.运行mongod --master启动主服务器.运行mongod --slave --source ma ...

  10. NTP时间同步服务器设置

    一.Window Server设置 [服务器端设置]1) 修改注册表以下键值:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\ ...