普通装饰器

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. Python 基礎 - 元組與簡易購物車實做

    tuple(元組) 其實跟列表差不多,也是存一組數,只不過是它一旦建立了,就不能修改了,只能做 切片 跟 查詢,所以只叫 只讀列表 語法: name = ("Rogers", &q ...

  2. 利用BeanUtils在对象间复制属性

    commons-beanutils是jakarta commons子项目中的一个软件包,其主要目的是利用反射机制对JavaBean的属性进行处理.我们知道,一个JavaBean通常包含了大量的属性,很 ...

  3. 2016年5月面试题(Unity&iOS)

    NGUI的DrawCall drawcall定义:对底层图形程序(比如:OpenGL ES)接口的调用,以在屏幕上画出东西. List在内存中连续的空间保存 List是线性直接存储类型 mipMap是 ...

  4. 如何换ionic里面的图标

    (转自http://www.zcool.com.cn/article/ZMTM4NDQw.html) 第一步,你把你的项目的SVG文件跟你自己做的图标的SVG文件都上到icomoon.io/app(上 ...

  5. c语言数据结构之 快速排序

    编译器:VS2013 #include "stdafx.h"#include<stdlib.h> //函数声明 void QuickSort(int a[],int n ...

  6. 计算机网络自学之路------IP协议(1)

    1)TCP/IP模型与OSI对应 2)TCP/IP集每层主要协议 3)IP协议 4)IP地址的命名与使用 5)子网与子网掩码 1)TCP/IP模型与OSI对应关系 我们看到,TCP/IP只有四层与OS ...

  7. POJ1986 Distance Queries (LCA)(倍增)

    Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12950   Accepted: 4577 ...

  8. 逻辑操作符“&&”的三层理解

    第一层:操作符“&&”可以对两个布尔值进行逻辑与运算,返回一个布尔值. 第二层:操作符“&&”可以对两个真假值进行逻辑与运算,并且返回一个真假值. 第三层:操作符“&a ...

  9. Majority Element II

    Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit ...

  10. kuangbin_SegTree D (POJ 2528)

    讲道理我之前暂时跳过染色的题是因为总觉得有什么很高端的算法来query 直到我做了F题(ZOJ 1610)才发现就是个暴力统计.....也对 也就几万个长度单位而已.... F就不po上来了 选了有点 ...