python 装饰器 Decorators

为什么80%的码农都做不了架构师?>>>   hot3.png

装饰器,就是对被装饰的对象进行修改,其语法以@开头,然后是装饰器函数的名字和可选参数。然后是被装饰的对象及可选参数。格式如下:

@decorator(agrs)
def func(func_args):
    ...

为了更容易理解装饰器,要先了解下python的特性。python中一切都是对象,函数是对象,类是对象,类的实例也是对象,函数名和类名可以作为参数传递,函数名和类名后面加(), 表示调用函数和类实例化。

1.函数和方法装饰器

语法格式

类似如下:

@decorator()
def func():
    ...

它实际上等价于:

def func():
    ...
func=decorator(func)

因为func=decorator(func), 所以调用func,func() = decorator(func)(), 大概原理就是这样。来看看一个完整的装饰器。

>>> def decorator(func):
	def wrapper():
		print 'in decorator'
		func()
	return wrapper

>>> @decorator
    def func():
	print 'in func'

>>> func

>>> func()
in decorator
in func

装饰器或被装饰的对象带有参数。

语法格式如下:

@decorator(argA, argB, ...)
def func(arg1, arg2, ...):
    pass

它实际上等价于:

def func(arg1, arg2, ...):
    pass
func=decorator(argA, argB, ...)(func)

所以,func(arg1, arg2, ... ) = decorator(argA, argB, ...)(func)(arg1, arg2, ... )。看个带参数装饰器的例子,

>>> def decorator(*arg_deco):
	def deco(func):
	    def wrapper(*arg_func):
		print 'in decorator, arg_deco:', arg_deco
		func(*arg_func)
	    return wrapper
	return deco

>>> @decorator('decorator args')
    def func(*arg_func):
	print 'in func, arg_func:', arg_func
>>> func('func args')
in decorator, arg_deco: ('decorator args',)
in func, arg_func: ('func args',)


装饰器嵌套,

语法格式如下:

@A
@B
@C
def f ():
    ...

上面代码实际上等价于:

def f():
     ...
f = A(B(C(f)))


2.类装饰器

语法和函数装饰器类似:

>>> @decortor
    class A:
	pass

当实例化时,a=A(), 实际上等价于下面代码:

class A:
    pass    
A=decorator(A)
a=A()

如何实现呢。

>>> def decorator(cls):
	class Wrapper:
		def __init__(self, *args):
			self.wrapped = cls(*args)
		def __getattr__(self, name):
			return getattr(self.wrapped, name)
	return Wrapper

>>> @decorator
class A:
	def __init__(self,x,y):
	    self.attr = 'aaa'
>>> a.attr
'aaa'


被装饰器装饰的方法或类,其属性发生了变化,如何保留呢。functools.wraps可以将装饰过的函数属性保留


转载于:https://my.oschina.net/mxs/blog/390825

你可能感兴趣的:(python 装饰器 Decorators)