Python高级编程 读书笔记: 1、 第1章_装饰器

# -*- 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() 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值