python中的装饰器详解

作者:junjie 时间:2022-08-14 04:32:05 

在了解装饰器的之前一定要先了解函数作为参数传递, 什么是函数内嵌,请参考我之前写的博客函数简介

因为在python里面,函数也是对象,也可以作为参数进行传递.python装饰器本质也是一种特殊函数,它接收的参数是函数对象,然后动态地函数参数添加额外的功能,而不用修改原有的函数对象.python装饰器传入的参数是函数,返回的值也是函数!
python装饰器思想有点类似设计模式的装饰模式, 其意图是动态地给函数对象添加额外的功能.比如像增加日志打印的功能,有点面向切面编程(AOP)的感觉.
装饰器语法

以@开头,接着后面跟着的是装饰器的名字和可选的参数.装饰器语法是一种语法糖.
格式如下


@decomaker(deco_args)
    def foo(func_opt_args)


可以组合,等价于foo = g(f(foo))


@g
@f
def foo():
    statement


简单装饰器

实例


#!/usr/bin/python
def  deco(func):
    print 'start'
    func()
    print 'end'
    return func

@deco
def foo():
    print 'In foo'

foo()
foo()

输出


start
In foo
end
In foo
In foo


带内嵌函数装饰器

内嵌函数保证每次新函数都被调用.而且被装饰的函数可以带有参数.
实例


def  deco(func):
    def _deco(x):    #该函数为内嵌函数
        print 'start'
        func(x)
        print 'end'
    return _deco

@deco
def foo(x):
    print 'In foo, get value is: %d' % x

foo(123456)

输出:


start
In foo, get value is: 123456
end


带参数的装饰器

需要自己返回以函数作为参数的装饰器。换句话说,decomaker()用 deco_args 做了些事并返回函数对象,而该函数对象正是以 foo 作为其参数的装饰器。简单的说来:foo=decomaker(deco_args)(foo)

实例


def deco(arg):
    def wrapper1(func):
        def _deco(x):
            print "get type is: ", arg
            func(x)
        return _deco

    def wrapper2(func):
        def _deco(x):
            func(x)
            print "get type is: ", arg
        return _deco

    if arg == 'type1':
        return wrapper1
    else:
        return wrapper2

@deco("type2")
def foo(x):
    print 'In foo: ', x

foo(123)

输出


In foo:  123
get type is:  type2


总结

装饰器本质是高阶的函数,可以装饰其他函数,增加被装饰函数的功能,但不能覆盖或改变被装饰函数原有的行为.对于被装饰的函数来说,装饰器是透明的.装饰器传入参数为函数,返回的函数是被装饰的函数.最后我们来实现给一个函数添加打印日志的功能,而不用改变这个函数.


#!/usr/bin/python
#coding=utf-8
import functools

def log(prefix, suffix):
    def deco(func):
        @functools.wraps(func)
        def wrapper(*args, **kargs):
            print '%s log start' % prefix
            print('get a is: %s' % args[0])
            print('get b is: %s' % args[1])
            print('get c is: %s' % args[2])
            print('get d is: %s' % kargs['d'])
            print('get d is: %s' % kargs['f'])
            func(*args, **kargs)
            print '%s log end' % suffix
        return wrapper
    return deco

@log('logstart', 'logend')
def test(a, b, c, d, f):
    print 'call func name is: %s' % test.__name__

test(1, 2, 3, d = 'dddd', f = 'ffff')

输出:


logstart log start
get a is: 1
get b is: 2
get c is: 3
get d is: dddd
get d is: ffff
call func name is: test
logend log end

标签:python,装饰器
0
投稿

猜你喜欢

  • javascript 版 Bad Apple 字符动画

    2010-01-28 12:19:00
  • 960网格系统

    2009-02-17 12:22:00
  • Python2.x版本中maketrans()方法的使用介绍

    2021-02-14 21:04:25
  • python 制作简单的音乐播放器

    2022-09-12 14:30:44
  • php通过隐藏表单控件获取到前两个页面的url

    2023-11-16 04:00:08
  • pytorch 实现张量tensor,图片,CPU,GPU,数组等的转换

    2023-08-12 07:44:34
  • 详解使用 pyenv 管理多个版本 python 环境

    2023-11-01 03:40:05
  • python3.6中anaconda安装sklearn踩坑实录

    2023-03-16 19:17:15
  • Python新手如何进行闭包时绑定变量操作

    2021-05-01 15:23:55
  • 分享一些可视信息设计资源

    2009-10-06 15:19:00
  • 鼠标实现图片的渐有渐无

    2013-06-30 02:49:10
  • python实现单机五子棋对战游戏

    2022-01-11 04:38:10
  • Go gRPC服务客户端流式RPC教程

    2023-07-16 06:08:55
  • .net新兴日志框架Serilog简介

    2023-06-28 16:20:05
  • python实现简单的购物程序代码实例

    2022-09-03 05:29:13
  • 自动定时重启sql server回收内存

    2008-11-26 17:41:00
  • getElementsByAttribute

    2009-10-27 12:13:00
  • 基于PHP常用文件函数和目录函数整理

    2023-06-09 22:02:34
  • asp使用模板生成静态页面方法详解

    2007-09-24 12:29:00
  • 如何使用PHP计算上一个月的今天

    2023-11-15 14:16:25
  • asp之家 网络编程 m.aspxhome.com