装饰器的应用场景附加功能

数据的清理或添加:函数参数类型验证 @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

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

时间: 2020-04-10

python装饰器使用实例详解

这篇文章主要介绍了python装饰器使用实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python装饰器的作用就是在不想改变原函数代码的情况下,增加新的功能.主要应用了python闭包的概念,现在用1个小例子说明 import time def foo(): time.sleep(1) def bar(): time.sleep(2) def show_time(f): def inner(): start_time = time.t

Python3.7 新特性之dataclass装饰器

Python 3.7中一个令人兴奋的新特性是 data classes . 数据类通常是一个主要包含数据的类,尽管实际上没有任何限制. 它是使用新的 @dataclass 装饰器创建的,如下所示: from dataclasses import dataclass @dataclass class DataClassCard: rank: str suit: str 此代码以及本教程中的所有其他示例仅适用于 Python 3.7 及更高版本. 注意: 当然在 Python 3.6 版本也可以使用

Python @property装饰器原理解析

这篇文章主要介绍了Python @property装饰器原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.通过@property装饰器,可以直接通过方法名来访问方法,不需要在方法名后添加一对"()"小括号. class Person: def __init__(self, name): self.__name = name @property def say(self): return self.__name xioabai

python使用装饰器作日志处理的方法

装饰器这东西我看了一会儿才明白,在函数外面套了一层函数,感觉和java里的aop功能很像:写了2个装饰器日志的例子, 第一个是不带参数的装饰器用法示例,功能相当于给函数包了层异常处理,第二个是带参数的装饰器用法示例,将日志输出到文件. ``` #coding=utf8 import traceback import logging from logging.handlers import TimedRotatingFileHandler def logger(func): def inner(*

python函数装饰器之带参数的函数和带参数的装饰器用法示例

本文实例讲述了python函数装饰器之带参数的函数和带参数的装饰器用法.分享给大家供大家参考,具体如下: 1. 函数带多个参数 # 普通的装饰器, 打印函数的运行时间 def decrator(func): def wrap(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print('运行时间为', end_time-start_time) return

python中property和setter装饰器用法

作用:调用方法改为调用对象, 比如 : p.set_name() 改为 p.set_name 区别:前者改变get方法,后者改变set方法 效果图: 代码: class Person: def __init__(self,name): self._name = name def get_name(self): return self._name def set_name(self,name): self._name = name p = Person('小黑') print(p.get_name

python装饰器练习题及答案

这篇文章主要介绍了python装饰器练习题及答案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一:编写装饰器,为多个函数加上认证的功能(用户的账号密码) 要求登录成功一次,后续的函数都无需输入用户名和密码 FLAG=False#此时还未登录 全局变量 写这个步骤的意义在于:方便 知道已经登录成功了,就不再重复登录 def login(func):#为多个函数加上的认证功能 def inner(*args,**kwargs):#加上装饰器 gl

python装饰器实例大详解

一.作用域 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我们要理解两点: a.在全局不能访问到局部定义的变量 b.在局部能够访问到全局定义的变量,但是不能修改全局定义的变量(当然有方法可以修改) 下面我们来看看下面实例: x = 1 def funx(): x = 10 print(x) # 打印出10 funx() print(x) # 打印出1 如果局部没有定义变量x,那么函数内部会从内往

Python 装饰器深入理解

讲 Python 装饰器前,我想先举个例子,虽有点污,但跟装饰器这个话题很贴切. 每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我们想到的一个办法就是把内裤改造一下,让它变得更厚更长,这样一来,它不仅有遮羞功能,还能提供保暖,不过有个问题,这个内裤被我们改造成了长裤后,虽然还有遮羞功能,但本质上它不再是一条真正的内裤了.于是聪明的人们发明长裤,在不影响内裤的前提下,直接把长裤套在了内裤外面,这样内裤还是内裤,有了长裤后宝宝再也不冷了.装饰器就像我们这里说的长裤,在不

使用Python装饰器在Django框架下去除冗余代码的教程

Python装饰器是一个消除冗余的强大工具.随着将功能模块化为大小合适的方法,即使是最复杂的工作流,装饰器也能使它变成简洁的功能. 例如让我们看看Django web框架,该框架处理请求的方法接收一个方法对象,返回一个响应对象: def handle_request(request): return HttpResponse("Hello, World") 我最近遇到一个案例,需要编写几个满足下述条件的api方法: 返回json响应 如果是GET请求,那么返回错误码 做为一个注册api

深入理解Python装饰器

装饰器简介: 装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法或者类进行加工.在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果.相对于其它方式,装饰器语法简单,代码可读性高.因此,装饰器在Python项目中有广泛的应用. 装饰器最早在Python 2.5中出现,它最初被用于加工函数和方法这样的可调用对象(callable object,这样的对象定义有__call__方法).在Python 2

python装饰器初探(推荐)

一.含有一个装饰器 #encoding: utf-8 ############含有一个装饰器######### def outer(func): def inner(*args, **kwargs):#要装饰f1(),这里用这俩形式参数,可以接受任意个参数,不管f1定义几个参数 print "1" r = func(*args, **kwargs)#这里要用func,不要用f1 print "2" return r return inner @outer #这里ou

深入浅出分析Python装饰器用法

本文实例讲述了Python装饰器用法.分享给大家供大家参考,具体如下: 用类作为装饰器 示例一 最初代码: class bol(object): def __init__(self, func): self.func = func def __call__(self): return "{}".format(self.func()) class ita(object): def __init__(self, func): self.func = f

Python装饰器基础详解

装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法或者类进行加工.在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果.相对于其它方式,装饰器语法简单,代码可读性高.因此,装饰器在Python项目中有广泛的应用. 前面快速介绍了装饰器的语法,在这里,我们将深入装饰器内部工作机制,更详细更系统地介绍装饰器的内容,并学习自己编写新的装饰器的更多高级语法. 什么是装饰器 装饰是为函数和类指定管理代码的一种

python装饰器与递归算法详解

1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说明一下: 小P闲来无事,随便翻看自己以前写的一些函数,忽然对一个最最最基础的函数起了兴趣: def sum1(): sum = 1 + 2 print(sum) sum1() 此时小P想看看这个函数执行用了多长时间,所以写了几句代码插进去了: import time def sum1(): star

Python装饰器实现几类验证功能做法实例

最近新需求来了,要给系统增加几个资源权限.尽量减少代码的改动和程序的复杂程度.所以还是使用装饰器比较科学 之前用了一些登录验证的现成装饰器模块.然后仿写一些用户管理部分的权限装饰器. 比如下面这种 def permission_required(permission): def decorator(f): @wraps(f) def decorated_function(*args, **kwargs): if not current_user.can(permission): abort(40

Python装饰器入门学习教程(九步学习)

装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法或者类进行加工.在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果.相对于其它方式,装饰器语法简单,代码可读性高.因此,装饰器在Python项目中有广泛的应用. 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 # -*- coding:gbk -*- '''示例1: 最简单的函数,表

python中装饰器的作用_Python装饰器详解,详细介绍它的应用场景相关推荐

  1. python中bool函数的作用_Python内置bool函数详细介绍

    英文文档: classbool([x]) Return a Boolean value, i.e. one of True or False. x is converted using the sta ...

  2. python迭代器和生成器的作用_python迭代器与生成器的详细介绍

    一.什么玩意是迭代器? 先说说什么是迭代吧,迭代就是一件事情重复很多次,比如说for循环. for循环可以对一切有iter方法的对象进行迭代,那么什么是iter方法呢? 一个对象是否可迭代,全都取决于 ...

  3. python中open函数打开文件_Python open函数详解:打开指定文件

    掌握了各种操作目录字符串或目录的函数之后,接下来可以准备读写文件了.在进行文件读写之前,首先要打开文件. Python 提供了一个内置的 open() 函数,该函数用于打开指定文件. open() 函 ...

  4. python os模块安装方法_基于python中pygame模块的Linux下安装过程(详解)

    一.使用pip安装Python包 大多数较新的Python版本都自带pip,因此首先可检查系统是否已经安装了pip.在Python3中,pip有时被称为pip3. 1.在Linux和OS X系统中检查 ...

  5. python数组相减_对Python 中矩阵或者数组相减的法则详解

    对Python 中矩阵或者数组相减的法则详解 最近在做编程练习,发现有些结果的值与答案相差较大,通过分析比较得出结论,大概过程如下: 定义了一个计算损失的函数: def error(yhat,labe ...

  6. 站长在线Python精讲:在Python中使用正则表达式的split()方法分割字符串详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<在Python中使用正则表达式的split()方法分割字符串详解>. 使用正则表达式分割字符串 在Python中使用正则表达 ...

  7. python中requests库的用途-python中requests库session对象的妙用详解

    在进行接口测试的时候,我们会调用多个接口发出多个请求,在这些请求中有时候需要保持一些共用的数据,例如cookies信息. 妙用1 requests库的session对象能够帮我们跨请求保持某些参数,也 ...

  8. Python中第三方库Requests库的高级用法详解

    Python中第三方库Requests库的高级用法详解 虽然Python的标准库中urllib2模块已经包含了平常我们使用的大多数功能,但是它的API使用起来让人实在感觉不好.它已经不适合现在的时代, ...

  9. 站长在线Python精讲:在Python中使用正则表达式的sub()方法替换字符串详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<在Python中使用正则表达式的sub()方法替换字符串详解>. 在Python中使用正则表达式的sub()方法替换字符串. ...

  10. python url解码_对python中url参数编码与解码的实例详解

    一.简介 在python中url,对于中文等非ascii码字符,需要进行参数的编码与解码. 二.关键代码 1.url编码 对字符串编码用urllib.parse包下的quote(string, saf ...

最新文章

  1. socket不能bind请求的地址_socket通信原理
  2. postgres使用dblink
  3. [Medical Image Process] 3.3 Grayscale Morphology Application
  4. LINUX - /etc/init.d/nginx: line 51: kill: (29833) - No such process
  5. QT跨平台项目开发经验(项目打包)
  6. 写给即将入行以及刚入行的程序员,你需要注意的几个点,别忽略!
  7. 【华为云分享】应用系统迁移华为云评估
  8. java遍历范型list_Java 集合(1)-- 俯瞰 Java 集合源码以及分类
  9. 揭秘淘宝286亿海量图片存储与处理架构
  10. 中兴手机怎么与计算机连接网络连接不上,ZTE中兴为什么wifi连接上却不能上网...
  11. 春节宅家玩什么?8款小游戏陪你一起过年
  12. 淮师计算机网络题库,淮阴师范学院(淮师)计算机基础一至六章习题
  13. 小学计算机课基础知识教案,小学信息技术公开课教案
  14. 题解1205汉诺塔问题
  15. 在线画图工具-venn维恩图
  16. laravel图形验证码(借用了TP的图形验证码类)非常好用简单,非常适合前后端分离的项目
  17. android 带箭头提示框,三种带箭头提示框总结实例
  18. 2015年8月之 英雄不老
  19. python的符号怎么打_python plt可视化――打印特殊符号和制作图例代码
  20. k8s 拉取镜像失败_Kubernetes:如何解决从k8s.gcr.io拉取镜像失败问题

热门文章

  1. C语言函数知识体系大学霸IT达人
  2. Wireshark安装失败或找不到网络接口问题
  3. Xamarin Essentials教程打开文件
  4. ​Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机
  5. python同步异步_python中Tornado的同步与异步I/O的介绍(附示例)
  6. MATLAB APPbase,使用HTTPD做内部访问转向
  7. python连接sqlserver_python 链接sqlserver 写接口实例
  8. 好东西+php,推荐个好东西swoole,php如虎添翼
  9. 微秒时间_揭秘奇特光速原子研究,记录有史以来最短时间段
  10. seaborn系列 (18) | 线性回归图regplot()