Decorator使用
下述的装饰器都可以为方法和类进行装饰
装饰器是一个语法糖,说白就是一种语法格式,
但是也可以不用这种语法,而是使用原生的调用,
最近看的几个开源代码,有这样的使用
1. 不带参数的方法装饰器
decorator_def_without_args.py
# coding: utf-8
from functools import wraps
def decorate_test(func):
#需要使用wraps防止改变方法名
@wraps(func)
def wrap(*args, **kwargs):
print('This is a decorate')
print('func name {}'.format(func.__name__))
return func(*args, **kwargs)
return wrap
@decorate_test
def say_hello():
return 'say hello'
def say_hello_none():
return 'say hello'
class TestSay(object):
@decorate_test
def say_hello(self):
return 'say hello'
if __name__ =="__main__":
print(say_hello())
print("-"*30)
print(decorate_test(say_hello_none)())
print("-"*30)
test = TestSay()
print(test.say_hello())
2. 带参数的方法装饰器
decorator_def_with_args.py
#coding:utf-8
from functools import wraps
def decorate_args(name):
def warp(func):
@wraps(func)
def warp_func(*args, **kwargs):
print('{} say:'.format(name))
return func(*args, **kwargs)
return warp_func
return warp
@decorate_args(name='zxc')
def say_hello():
return ' hello'
def say_hello_none():
return ' hello'
class TestSay(object):
@decorate_args(name='zxc')
def say_hello(self):
return ' hello'
if __name__ =="__main__":
print(say_hello())
print("-"*30)
print(decorate_args(name='zcx')(say_hello_none)())
print("-"*30)
test = TestSay()
print(test.say_hello())
3.不带参数的类装饰器
decorator_cls_without_args.py
与带参数的实现有点不一样,这里讲func作为类初始化的一部分传入,使用类装饰器后,在调用 func 函数的过程中其对应的 instance 并不会传递给 call 方法,造成其 mehtod unbound,需要是用描述符进行绑定
#coding:utf-8
from functools import wraps
class decorate_class(object):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print('This is a class decorate')
return self.func(*args, **kwargs)
def __get__(self, instance, owner):
return lambda *args, **kwargs: self.func(instance, *args, **kwargs)
@decorate_class
def say_hello(what):
return 'say {}'.format(what)
def say_hello_none(what):
return 'say {}'.format(what)
class TestSay(object):
@decorate_class
def say_hello(self,what):
return 'say {}'.format(what)
if __name__=="__main__":
print(say_hello('hello'))
print("-"*30)
print(decorate_class(say_hello_none)('hello'))
print("-"*30)
test = TestSay()
print(test.say_hello("hello"))
4.带参数的类装饰器
decorator_cls_with_args.py
这个实现的话,讲参数作为class初始化的一部分,而方法是通过call传入的,就没有上面那个问题了
#coding:utf-8
class decorate_args_class(object):
def __init__(self, name):
self.name = name
def __call__(self, func):
def warp(*args, **kwargs):
print('{} say:'.format(self.name))
return func(*args, **kwargs)
return warp
@decorate_args_class(name='zxc')
def say_hello(what):
return '{:>13}'.format(what)
def say_hello_none(what):
return '{:>13}'.format(what)
class TestSay(object):
@decorate_args_class(name='zidy')
def say_hello(self,what):
return '{:>13}'.format(what)
if __name__=="__main__":
print(say_hello('hello'))
print("-"*30)
d_a_class = decorate_args_class(name='zxc')
print(d_a_class(say_hello_none)('hello'))
print("-"*30)
a = TestSay()
print(a.say_hello('hello'))
(于2017年3月19日,http://blog.csdn.net/bzd_111)