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 ...
随机推荐
- 解决Android应用安装快完毕时提示签名冲突
最近开发了一个Android手机应用,自己用Eclipse调试安装没问题,使用其他人调试生成的bin下的apk就会出现问题,安装到最后提示"安装签名冲突"错误,想了一下估计是没有给 ...
- 学android: android-studio从main开始
android-studio 创建hello world很容易,一路next创建blank activity,再接好手机或者avd(andorid virtual device)就好了. 但是对于我 ...
- css中的大小、定位、轮廓相关属性
css中的大小.定位.轮廓相关属性 1.通过height.width属性控制组件大小 height:高度,可以设置任何有效的距离值: width:宽度,可以设置任何有效的属性值: max-height ...
- 自执行函数与setTimeout结合计算
var v1=0,v2=0,v3=0; for(var i=1;i<=3;i++){ var i2=i; (function(){ ...
- Android学习
http://www.jikexueyuan.com/path/android 一.概述: 03年10月建立android科技,05年8月被google收购,07年11月成立开放手持设备联盟(Open ...
- HDU2647
第一道逆拓扑纪念一下... #include<iostream> #include<cstdio> #include<cstring> #include<cm ...
- DFS序详解
dfs序就是一棵树在dfs遍历时组成的节点序列. 它有这样一个特点:一棵子树的dfs序是一个区间. 下面是dfs序的基本代码: void dfs(int x,int pre,int d){//L,R表 ...
- 【OpenGL】VAO与VBO
1.我们先了解什么是OpenGL对象(OpenGL Object) 根据OpenGL Wiki的定义: An OpenGL Object is an OpenGL construct that con ...
- Android proguard 详解
本文转载于:http://blog.csdn.net/banketree/article/details/41928175 简介 Java代码是非常容易反编译的.为了很好的保护Java源代码,我们往往 ...
- Form onsubmit 事件 阻止表单提交() 必须选中同意选项才可以提交
<!DOCTYPE html><html><head><meta charset="utf-8"><title>菜鸟教程 ...