普通装饰器

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. 在Unity中创建可远程加载的.unity3d包

    在一个Unity项目中,发布包本身不一定要包括所有的Asset(译为资产或组件),其它的部分可以单独发布为.unity3d,再由程序从本地/远程加载执行,这部分不在本文讨论范围.虽然Unity并没有直 ...

  2. REDIS 主从复制

      REDIS目前给出了一个异步的主从复制版本系统.在redis里 提供了几种方式来完成这个工作. 主从复制主要对应在redis/replication.c这个文件里.源码框架里 分为3部分: Mas ...

  3. 二叉树[C实现]

    #include<stdio.h> #include<malloc.h> #include<iostream> //定义节点 typedef struct BiNo ...

  4. Vim速查脑图

  5. svm损失函数

    作者:杜客链接:https://zhuanlan.zhihu.com/p/20945670来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. SVM的损失函数定义如下: 举 ...

  6. 前端学习 第七弹: Javascript实现图片的延迟加载

    前端学习 第七弹: Javascript实现图片的延迟加载 为了实现图片进入视野范围才开始加载首先: <img    src="" x-src="/acsascas ...

  7. Substring with Concatenation of All Words

    You are given a string, s, and a list of words, words, that are all of the same length. Find all sta ...

  8. linux 模块常用命令

    lsmod | grep pcspkr  查看pcspkr模块是否运行modprobe -r pcspkr   删除pcspkr模块modinfo pcspkr       查看pcspkr模块信息m ...

  9. Unity全视角游戏的键盘操作位移——研究笔记

    using UnityEngine; using System.Collections; public class MoveCeShi : MonoBehaviour { ; private Char ...

  10. pyside窗口关闭触发事件

    窗口关闭事件本质上是重写了类内部的closeEvent方法,可以通过重写这个类去实现其他你想要的关闭事件. 下面的例子实现了一个简单的窗口,并为窗口添加了关闭时弹出提示框的功能. import sys ...