# -*- encoding: utf-8 -*-
import functools
import json
'''
1、 第1章_装饰器
关键:
1 装饰器
本质: 是一个函数,该函数接受被装饰的函数作为其输入参数,返回修饰后的函数
顺序: 多个装饰器按照自底向上的顺序来应用它们
应用场景:
1) 附加功能: 例如检查身份
2) 数据清理或添加: 例如mock.patch为函数提供了作为附加位置参数创建的mock对象
3) 函数注册: 例如为任务运行器注册一个任务
4) 输出格式化: 例如将函数输出转换为json字符串
2 有参装饰器
三层函数套路。
最外层函数的参数是该装饰器需要的参数
中间函数的参数是被装饰函数本身
最里面函数的参数是被装饰函数的参数
样例:
def jsonOutputWithParams(indent=None, sort_keys=False):
def external(func):
@functools.wraps(func)
def inner(*args, **kwargs):
try:
result = func(*args, **kwargs)
except JSONOutputError as ex:
result = {
'status': 'error',
'message': str(ex)
}
return json.dumps(result, indent=indent, sort_keys=sort_keys)
return inner
return external
本质分析:
1)
如果是有参装饰器,那么注意:
@jsonOutputWithParams(indent=2)
def funcWithParams():
return {'score': '382'}
中:
jsonOutputWithParams(indent=2)
这个会被单独解释为一个函数,即external,并返回
此时:
@jsonOutputWithParams(indent=2)
def funcWithParams():
return {'score': '382'}
等同于
@external
def funcWithParams():
return {'score': '382'}
2) 分析
@external
def funcWithParams():
return {'score': '382'}
它声明了一个局部函数inner,并返回,等同于
external(funcWithParams) 此时调用inner方法
参考:
Python高级编程
'''
class User(object):
def __init__(self, name, email):
self.name = name
self.email = email
class AnonymousUser(User):
def __init__(self):
self.name = None
self.emaol = None
def __nonzero__(self):
return False
def authLogin(func):
@functools.wraps(func)
def wrapper(user, *args, **kwargs):
if user and isinstance(user, User):
return func(user, *args, **kwargs)
else:
raise ValueError('Need a valid user to auth')
return wrapper
class JSONOutputError(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return self.message
def jsonOutput(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
result = json.dumps(result)
return result
return wrapper
@jsonOutput
def func():
return {'score': 363}
def jsonOutputWithParams(indent=None, sort_keys=False):
def external(func):
@functools.wraps(func)
def inner(*args, **kwargs):
try:
result = func(*args, **kwargs)
except JSONOutputError as ex:
result = {
'status': 'error',
'message': str(ex)
}
return json.dumps(result, indent=indent, sort_keys=sort_keys)
return inner
return external
@jsonOutputWithParams(indent=2)
def funcWithParams():
return {'score': '382'}
def jsonOutputCompatiable(decoratedFunc=None, indent=None, sort_keys=False):
if decoratedFunc and (indent or sort_keys):
raise RuntimeError('Invalid parameters')
def external(func):
@functools.wraps(func)
def inner(*args, **kwargs):
try:
result = func(*args, **kwargs)
except JSONOutputError as ex:
result = {
'status': 'error',
'message': str(ex)
}
return json.dumps(result, indent=indent, sort_keys=sort_keys)
return inner
if decoratedFunc:
return external(decoratedFunc)
else:
return external
def process():
result = func()
print result
print type(result)
result = funcWithParams()
print result
print type(result)
if __name__ == "__main__":
process()