python修饰器怎样在类的层次中使用

Python011

python修饰器怎样在类的层次中使用,第1张

python在类使用装饰器有很多方法,下面是其中一个简单点的:

?

# -*- coding:utf-8 -*-

import inspect

import time

def service_wrap(func):

"""

对service func进行包装

"""

def wrapped(*args, **kwargs):

print(u' 时间: %s, <%s:%s> [ 参数:<%s %s>]' %

(time.time(),func.__module__, func.__name__, args, kwargs))

try:

ret = func(*args, **kwargs)

return ret

except Exception, e:

#TODO

raise e

return wrapped

class BaseService(object):

"""

所有的Service都从该类继承

"""

def __getattribute__(self, name):

value = object.__getattribute__(self, name)

if inspect.ismethod(value):

if str(name).startswith('__'): #过滤内置方法、属性

return value

return service_wrap(value)

else:

return value

装饰器是从英文decorator翻译过来的,从字面上来看就是对某个东西进行修饰,增强被修饰物的功能,下面我们对装饰器做下简单介绍。

一、怎么编写装饰器

装饰器的实现很简单,本质是一个可调用对象,可以是函数、方法、对象等,它既可以装饰函数也可以装饰类和方法,为了简单说明问题,我们实现一个函数装饰器,如下代码:

有了这个装饰器,我们就可以打印出什么时候开始和结束调用函数,对于排查函数的调用链非常方便。

二、带参数的装饰器

上面的例子无论什么时候调用sum都会输出信息,如果我们需要按需输出信息怎么实现呢,这时就要用到带参数的装饰器了,如下代码:

对sum使用装饰器时没有参数,这时debug为0,所以调用sum时不会输出函数调用相关信息。

对multi使用装饰器时有参数,这时debug为1,所以调用multi时会输出函数调用相关信息。

三、函数名字问题

当我们打印被装饰后的函数名字时,不知道大家有没发现输出的不是函数本身的名字,如下代码会输出‘wrap’而不是‘sum’:

有时这种表现并不是我们想要的,我们希望被装饰后的函数名字还是函数本身,那要怎么实现呢?很简单,只需要引入functools.wraps即可,如下代码就会输出‘sum’了:

看完后是不是觉得python装饰器很简单,只要了解它的本质,怎么写都行,有好多种玩法呢。