python装饰器实现aop_python中的装饰器详解

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

因为在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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值