装饰器的应用场景 附加功能 数据的清理或添加: 函数参数类型验证 @require_ints 类似请求前拦截 数据格式转换 将函数返回字典改为 json/YAML 类似响应后篡改 为函数提供额外的数据 mock.patch 函数注册 在任务中心注册一个任务 注册一个带信号处理器的函数

不同应用场景下装饰器实现

简单注册表 funcs = []

def register(func):

funcs.append(func)

return func

@register

def a():

return 3

@register

def b():

return 5

# 访问结果

result = [func() for func in funcs]

注册表隔离(使用类的不同实例) class Registry(object):

def __init__(self):

self._funcs = []

def register(self, func):

self._funcs.append(func)

def run_all(self):

return [func() for func in self._funcs]

r1 = Registry()

r2 = Registry()

@r1.register

def a():

return 3

@r2.register

def b():

return 5

@r1.register

@r2.register

执行时封装代码

类型检查 from functools import wraps

def require_ints(func):

@wraps(func) # 将func的信息复制给inner

def inner(*args, **kwargs):

for arg list(args) + list(kwargs.values()):

if not isinstance(arg, int:

raise TypeError("{} 只接受int类型参数".format(func.__name__)

return func(*args, **kwargs)

return inner

用户验证 from functools import wraps

class User(object):

def __init__(self, username, email):

self.username = username

self.email = email

class AnonymousUser(object):

def __init__(self):

self.username = self.email = None

def __nonzero__(self): # 将对象转换为bool类型时调用

return False

def requires_user(func):

@wraps(func)

def inner(user, *args, **kwargs): # 由于第一个参数无法支持self, 该装饰器不支持装饰类

if user and isinstance(user, User):

return func(use, *args, **kwargs)

else:

raise ValueError("非合法用户")

return inner

输出格式化 import json

from functools import wraps

def json_output(func): # 将原本func返回的字典格式转为返回json字符串格式

@wrap(func)

def inner(*args, **kwargs):

return json.dumps(func(*args, **kwargs))

return inner

异常捕获 import json

from functools import wraps

class Error1(Exception):

def __init__(self, msg):

self.msg = msg

def __str__(self):

return self.msg

def json_output(func):

@wrap(func)

def inner(*args, **kwargs):

try:

result = func(*args, **kwargs)

except Error1 as ex:

result = {"status": "error", "msg": str(ex)}

return json.dumps(result)

return inner

# 使用方法

@json_ouput

def error():

raise Error1("该条异常会被捕获并按JSON格式输出")

日志管理 import time

import logging

from functools import wraps

def logged(func):

@wraps(func)

def inner(*args, **kwargs): # *args可以装饰函数也可以装饰类

start = time.time()

result = func(*args, **kwargs)

exec_time = time.time() - start

logger = logging.getLoger("func.logged")

logger.warning("{} 调用时间:{:.2} 执行时间:{:.2}s 结果:{}".format(func.__name__, start, exec_time, result)

带参数的装饰器

带参数的装饰器相当于一个返回装饰器的函数,@deco(a=1)在调用@之前会首先执行deco(a=1)得到一个实际的装饰器, 带参数的装饰器deco(a=1)模块导入时立即执行

装饰类

为类增加可排序功能(而不通过继承子类扩充父类方法,比如多个类需要增加此功能时) import time

from functools import wraps

def sortable_by_created(cls):

original_init = cls.__init__

@wrap(original_init)

def new_init(self, *args, **kwargs):

original_init(*args, **kwargs)

self._created = time.time()

cls.__init__ = new_init

cls.__lt__ = lambda self, other: self._created < other._created

cls.__gt__ = lambda self, other: self._created > other._created

return cls

也可定义一个SortableByCreated()类, 子类使用多重继承其父类和SortableByCreated

类型转换

函数被装饰后有可能变为一个类的实例,此时为了兼容函数调用,应为所返回的类提供__call__方法 class Task(object):

def __call__(self, *args, **kwargs):

return self.run(*args, **kwargs)

def run(self, *args, **kwargs):

raise NotImplementedError("子类未实现该接口")

def task(func):

class SubTask(Task):

def run(self, *args, **kwargs):

func(*args, **kwargs)

return SubTask()

第二章 上下文管理器

定义

包装任意代码

确保执行的一致性

语法

with语句

__enter__和__exit__方法 class ContextManager(object):

def __init__(self):

self.entered = False

def __enter__(self):

self.entered = True

return self

def __exit__(self, exc_type, exc_instance, traceback):

self.entered = False

应用场景

资源清理 import pymysql

class DBConnection(object):

def __init__(self, *args, **kwargs):

self.args,self.kwargs = args, kwargs

def __enter__(self):

self.conn = pymysql.connect(*args, **kwargs)

return self.conn.cursor()

def __exit__(self, exc_type, exc_instance, trackback):

self.conn.close()

异常处理(避免重复)

传播异常(__exit__中return False)

终止异常(__exit__中return True) class BubleExceptions(object):

def __enter__(self):

return self

def __exit__(self, exc_type, exc_instance, trackback):

if exc_instance:

print("出现异常: {}".format(exc_instance)

return False # return True终止异常

处理特定的异常 class HandleValueError(object):

def __enter__(self):

return self

def __exit__(self, exc_type, exc_instance, trackback):

if not exc_type: return True

if issubclass(exc_type, ValueError):

print("处理ValueError: {}".format(exc_instance)

return False

if issubclass...语句改为if exec_type == ValueError则不处理ValueType的子类异常

也可以根据异常的属性来判断是否传播或终止

更简单的语法 import contextlib

@contextlib.contextmanager

def acceptable_error_codes(*codes):

try:

yield

except ShellException as exc_instance:

if exc_instance.code not in codes:

raise

pass

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持聚米学院。

python装饰器应用论文_Python装饰器的应用场景代码总结相关推荐

  1. python装饰器应用论文_python 装饰器应用

    1 注册回调函数 下面这个示例展示了通过URL的路由来调用相关注册的函数示例: class MyApp(): def __init__(self): self.func_map = {} def re ...

  2. python装饰器与闭包_Python 装饰器和闭包

    Python 装饰器和闭包 装饰器是 Python 中常见的语法糖,这篇文章讲了闭包和装饰器的原理,并且分析了函数中变量的作用域,以及尝试总结了常见的坑. 装饰器基础 首先来看看装饰器的定义:装饰器本 ...

  3. python中装饰器的作用_Python装饰器详解,详细介绍它的应用场景

    装饰器的应用场景附加功能 数据的清理或添加:函数参数类型验证 @require_ints 类似请求前拦截数据格式转换 将函数返回字典改为 JSON/YAML 类似响应后篡改为函数提供额外的数据 moc ...

  4. python重复字符串n次_python装饰器听了N次也没印象,读完这篇你就懂了

    装饰器其实一直是我的一个"老大难".这个知识点就放在那,但是拖延症... 其实在平常写写脚本的过程中,这个知识点你可能用到不多 但在面试的时候,这可是一个高频问题. 一.什么是装饰 ...

  5. python装饰器参数讲解_python装饰器的详细解析

    写在前面: python装饰器(fuctional decorators)就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能. 这个函数的特殊之处在于它的 ...

  6. python 装饰器有哪些_python装饰器有什么用

    简言之,python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能. 一般而言, ...

  7. python中的装饰器怎么运行_Python 装饰器入门(上)

    翻译前想说的话: 这是一篇介绍python装饰器的文章,对比之前看到的类似介绍装饰器的文章,个人认为无人可出其右,文章由浅到深,由函数介绍到装饰器的高级应用,每个介绍必有例子说明.文章太长,看完原文后 ...

  8. python自带装饰器详解_Python装饰器详解

    引言 装饰器简单来说是我们向一个现有的已经存在的函数或对象添加新的功能,同时呢我们又不用改变他现有的结构. 为什么我们需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye( ...

  9. python装饰器传递参数_Python装饰器高级版—Python类内定义装饰器并传递self参数...

    本文重点:解决了类里面定义的装饰器,在同一个类里面使用的问题,并实现了装饰器的类属性参数传递 目录: 一.基本装饰器 二.在类里定义装饰器,装饰本类内函数 三.类装饰器 正文: 一.基本装饰器 装饰不 ...

最新文章

  1. bzoj2020[Usaco2010 Jan]Buying Feed, II*
  2. Best open-source pedestrian detection library for commercial use?
  3. 用JQ去实现一个轮播效果
  4. Delphi项目的构成(Files That Make Up a Delphi Project)
  5. 蚂蚁动态卡片,让App首页实现敏捷更新
  6. 浅析若干Java序列化工具
  7. 开源开放 | 熵简科技 AI Lab 开源金融领域中文预训练语言模型 FinBERT
  8. mysql键太长_数据库,主键为何不宜太长长长长长长长长?(转)
  9. python图像对比度增强图片清晰度_Python 图像对比度增强的几种方法(小结)
  10. java之classpath到底是什么
  11. python 中list的操作(循环、切片、增、删、改、查、反转、排序)
  12. 使用salt-ssh批量管理主机
  13. 如何选择配置管理工具
  14. IconFont使用方式简介
  15. L1-022 奇偶分家(c)
  16. 【网络】VLAN 及其配置详解
  17. CSS角度单位(deg)
  18. 解析json数据 (js , java)
  19. 一篇文章学会日志logback的使用
  20. 电脑突然无法播放html音频,联想电脑突然没声音了音乐也播放不了,这到底是为什么啊...

热门文章

  1. Visual Studio下使用jQuery的10个技巧
  2. net中的调试javascript脚本
  3. 2.3_ 1_ 进程同步、进程互斥
  4. 数据库高级知识——mysql架构介绍(一)
  5. linux的系统移植——【PC-开发板】的环境搭建
  6. 计算机网络( 二十二)-数据链路层(补充)
  7. linux system函数传参,Linux系统调用例程system_call和参数传递
  8. android 2个界面抽屉,Android使用DrawerLayout创建左右两个抽屉菜单
  9. 开启httponly之后登陆失败_二次元约会模拟《少女都市》正式版登陆Steam 橘势大好...
  10. obs噪音抑制调多少合适_TVS瞬态抑制二极管的特性及应用