python 装饰器用法


# 装饰器的用法

# 1.一个简单的类型检查

def require_int(decorated):

def inner(*args,**kwargs):

kwargs_values = [i for i in kwargs.values()]

for a in (kwargs_values + list(args)):

if not isinstance(a,int):
raise TypeError('%s only accept interger as argument' % decorated.__name__)

return decorated(*args,**kwargs)
return inner

@require_int
def foo(x,y):
"sum of x and y"
return x+y



re = foo(1,2)
# print(re)
# print(help(foo))

#2.帮助保存信息***************************************************************


import functools

def require_int(decorated):
@functools.wraps(decorated)
def inner(*args,**kwargs):

kwargs_values = [i for i in kwargs.values()]

for a in (kwargs_values + list(args)):

if not isinstance(a,int):
raise TypeError('%s only accept interger as argument' % decorated.__name__)

return decorated(*args,**kwargs)
return inner

@require_int
def foo(x,y):
"sum of x and y"
return x+y


re = foo(1,2)
# print(re)
# print(help(foo))

#3.用户验证***************************************************************

class User(object):

def __init__(self,username,email):
self.username = username
self.email = email

class anonymousUser(User):

def __init__(self):
self.username = None
self.email = None

def __nonzero__(self):
return False

def requires_user(decorated):
@functools.wraps(decorated)
def inner(user,*args,**kwargs):
if user and isinstance(user,User):
return decorated(user,*args,**kwargs)
else:
raise ValueError('a valid user is required to run this')

return inner


#3.输出格式化***************************************************************

class JSONOutputError(Exception):
def __init__(self,message):
self._message = message

def __str__(self):
return self._message

import json
def json_output(decorted):
@functools.wraps(decorted)
def inner(*args,**kwargs):
try:
result = decorted(*args,**kwargs)
if result:
return json.dumps(result)
except JSONOutputError as e:
return json.dumps(
{
'status':'error',
'message':str(e)
}
)

return inner

@json_output
def do_nothing():
return {'status':'done'}

@json_output
def error():
raise JSONOutputError('this function is erratic')

print(error())

#4.日志管理***************************************************************

import time
import logging

def logged(decorated):
@functools.wraps(decorated)
def inner(*args,**kwargs):

start = time.time()
re_value = decorated(*args,**kwargs)
end = time.time()
delt = end - start
logger = logging.getLogger('decorated.logged')
logger.info('%s was called ,spennd time %f,result is %s' %(decorated.__name__,delt,re_value))

return re_value
return inner

@logged
def sleep(return_value):

time.sleep(2)
return return_value

print(sleep(8))

#4.向后兼容的装饰器***************************************************************

def json_output(decorated_= None,indent = None,sort_keys = False):

def actual_decorator(func):
@functools.wraps(func)
def inner(*args,**kwargs):
try:
result = func(*args, **kwargs)
if result:
return json.dumps(result,indent=indent,sort_keys=sort_keys)
except JSONOutputError as e:
return json.dumps(
{
'status': 'error',
'message': str(e)
},indent=indent,sort_keys=sort_keys
)

return inner

if decorated_:
return actual_decorator(decorated_)
else:
return actual_decorator

#4.类型转换(celery应用)***************************************************************

class Task(object):

def run(self):

raise NotImplementedError('subclasses must implement run')

def identify(self):
return 'i am a task'

def task(decorated):
"""将函数转换成类的装饰器"""
class TaskSubclass(Task):
def run(self,*args,**kwargs):
return decorated(*args,**kwargs)

return TaskSubclass

@task
def foo():
return 2+2

print(foo().run())
print(foo().identify())


#5.类型转换调用升级(celery应用)***************************************************************
class TaskUpdate(object):

def run(self):

raise NotImplementedError('subclasses must implement run')

def identify(self):
return 'i am a task'

def __call__(self, *args, **kwargs):
return self.run(*args, **kwargs)

def task(decorated):
"""将函数转换成类的装饰器"""
class TaskSubclass(TaskUpdate):
def run(self,*args,**kwargs):
return decorated(*args,**kwargs)

return TaskSubclass()

@task
def foo():
return 2+2

print(foo())
print(foo.identify())
posted @ 2020-07-28 10:07  ~相忘于江湖  阅读(155)  评论(0)    收藏  举报