基于Python 装饰器装饰类中的方法实例

title: Python 装饰器装饰类中的方法

comments: true
date: 2017-04-17 20:44:31
tags: ['Python', 'Decorate']
category: ['Python']
---

目前在中文网上能搜索到的绝大部分关于装饰器的教程,都在讲如何装饰一个普通的函数。本文介绍如何使用Python的装饰器装饰一个类的方法,同时在装饰器函数中调用类里面的其他方法。本文以捕获一个方法的异常为例来进行说明。

有一个类Test, 它的结构如下:

class Test(object):
 def __init__(self):
  pass
 def revive(self):
  print('revive from exception.')
  # do something to restore
 def read_value(self):
  print('here I will do something.')
  # do something.

在类中有一个方法read_value(),这个方法在多个地方被调用。由于某些原因,方法read_value有可能随机抛出Exception导致程序崩溃。所以需要对整个方法做try ... except处理。最丑陋的做法如下面的代码所示:

class Test(object):
 def __init__(self):
  pass
 def revive(self):
  print('revive from exception.')
  # do something to restore
 def read_value(self):
  try:
   print('here I will do something.')
   # do something.
  except Exception as e:
   print(f'exception {e} raised, parse exception.')
   # do other thing.
   self.revive()

这样写虽然可以解决问题,但是代码不Pythonic。

使用装饰器来解决这个问题,装饰器函数应该写在类里面还是类外面呢?答案是,写在类外面。那么既然写在类外面,如何调用这个类的其他方法呢?

首先写出一个最常见的处理异常的装饰器:

def catch_exception(origin_func):
 def wrapper(*args, **kwargs):
  try:
   u = origin_func(*args, **kwargs)
   return u
  except Exception:
   return 'an Exception raised.'
 return wrapper
class Test(object):
 def __init__(self):
  pass
 def revive(self):
  print('revive from exception.')
  # do something to restore
 @catch_exception
 def read_value(self):
  print('here I will do something.')
  # do something.

这种写法,确实可以捕获到origin_func()的异常,但是如果在发生异常的时候,需要调用类里面的另一个方法来处理异常,这又应该怎么办?答案是给wrapper增加一个参数:self.

代码变为如下形式:

def catch_exception(origin_func):
 def wrapper(self, *args, **kwargs):
  try:
   u = origin_func(self, *args, **kwargs)
   return u
  except Exception:
   self.revive() #不用顾虑,直接调用原来的类的方法
   return 'an Exception raised.'
 return wrapper
class Test(object):
 def __init__(self):
  pass
 def revive(self):
  print('revive from exception.')
  # do something to restore
 @catch_exception
 def read_value(self):
  print('here I will do something.')
  # do something.

只需要修改装饰器定义的部分,使用装饰器的地方完全不需要做修改。

下图为正常运行时的运行结果:

下图为发生异常以后捕获并处理异常:

通过添加一个self参数,类外面的装饰器就可以直接使用类里面的各种方法,也可以直接使用类的属性。

以上这篇基于Python 装饰器装饰类中的方法实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Python中的各种装饰器详解
  • Python的装饰器使用详解
  • Python 装饰器使用详解
  • python类装饰器用法实例
  • 深入理解Python中装饰器的用法
  • Python中的装饰器用法详解
  • 简单说明Python中的装饰器的用法
(0)

相关推荐

  • python类装饰器用法实例

    本文实例讲述了python类装饰器用法.分享给大家供大家参考.具体如下: #!coding=utf-8 registry = {} def register(cls): registry[cls.__clsid__] = cls return cls @register class Foo(object): __clsid__ = '123-456' def bar(self): pass print registry 运行结果如下: {'123-456': <class '__main__.F

  • Python的装饰器使用详解

    Python有大量强大又贴心的特性,如果要列个最受欢迎排行榜,那么装饰器绝对会在其中. 初识装饰器,会感觉到优雅且神奇,想亲手实现时却总有距离感,就像深闺的冰美人一般.这往往是因为理解装饰器时把其他的一些概念混杂在一起了.待我抚去层层面纱,你会看到纯粹的装饰器其实蛮简单直率的. 装饰器的原理 在解释器下跑个装饰器的例子,直观地感受一下. # make_bold就是装饰器,实现方式这里略去 >>> @make_bold ... def get_content(): ... return '

  • 深入理解Python中装饰器的用法

    因为函数或类都是对象,它们也能被四处传递.它们又是可变对象,可以被更改.在函数或类对象创建后但绑定到名字前更改之的行为为装饰(decorator). "装饰器"后隐藏了两种意思--一是函数起了装饰作用,例如,执行真正的工作,另一个是依附于装饰器语法的表达式,例如,at符号和装饰函数的名称. 函数可以通过函数装饰器语法装饰: @decorator # ② def function(): # ① pass 函数以标准方式定义.① 以@做为定义为装饰器函数前缀的表达式②.在 @ 后的部分必须

  • Python中的各种装饰器详解

    Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: 复制代码 代码如下: >>> def test(func):     def _test():         print 'Call the function %s().'%func.func_name         return func()     return _test >

  • Python中的装饰器用法详解

    本文实例讲述了Python中的装饰器用法.分享给大家供大家参考.具体分析如下: 这里还是先由stackoverflow上面的一个问题引起吧,如果使用如下的代码: 复制代码 代码如下: @makebold @makeitalic def say():    return "Hello" 打印出如下的输出: <b><i>Hello<i></b> 你会怎么做?最后给出的答案是: 复制代码 代码如下: def makebold(fn):    

  • Python 装饰器使用详解

    装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象. 经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓存.权限校验等场景.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用. 先来看一个简单例子: def now(): print('2017_7_29') 现在有一个新的需求,希望可以记录下函数的执行日志,于是在代码中添加日志代码: def now():

  • 简单说明Python中的装饰器的用法

    装饰器对与Python新手以至于熟悉Python的人都是一个难理解, 难写的东西. 那么今天就分享一下我对Python 装饰器的理解 所谓装饰器仅仅是一种语法糖, 可作用的对象可以是函数也可以是类, 装饰器本身是一个函数, 其主要工作方式就是将被装饰的类或者函数当作参数传递给装饰器函数, 比如定义如下装饰器 import time def run_time(func): def wrapper(*args, **kwargs): start = time.time() r = func(*arg

  • 基于Python 装饰器装饰类中的方法实例

    title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] category: ['Python'] --- 目前在中文网上能搜索到的绝大部分关于装饰器的教程,都在讲如何装饰一个普通的函数.本文介绍如何使用Python的装饰器装饰一个类的方法,同时在装饰器函数中调用类里面的其他方法.本文以捕获一个方法的异常为例来进行说明. 有一个类Test, 它的结构如下: clas

  • 利用python爬取斗鱼app中照片方法实例

    前言 没想到python是如此强大,令人着迷,以前看见图片总是一张一张复制粘贴,现在好了,学会python就可以用程序将一张张图片,保存下来. 最近看到斗鱼里的照片都不错,决定用最新学习的python技术进行爬取,下面将实现的过程分享出来供大家参考,下面话不多说了,来一起看看详细的介绍吧. 方法如下: 首先下载一个斗鱼(不下载也可以,url都在这了对吧) 通过抓包,抓取到一个json的数据包,得到下面的地址 观察测试可知,通过修改offset值就是相当于app的翻页 访问这个url,返回得到的是

  • SQL Server中调用C#类中的方法实例(使用.NET程序集)

    需求是这样的,我在.net程序里操作数据时将一些字段数据加密了,这些数据是很多系统共用的,其中一delphi程序也需要用到,并且需要将数据解密,由于我在.net里加密的方式比较特殊,在delphi程序里解密比较繁琐且要消耗很多时间,所以不得不让sqlserver调用程序集的方式来解决问题. 下面只是一个例子,贴出来共享. 建立一个dll,class,代码如下: 复制代码 代码如下: namespace MyDll {     public partial class MyClass     {

  • Python学习之装饰器与类的装饰器详解

    目录 装饰器 装饰器的定义 装饰器的用法 类中的装饰器 类的装饰器-classmethod 类的装饰器-staticmethod 类的装饰器-property 通过学习装饰器可以让我们更好更灵活的使用函数,通过学会使用装饰器还可以让我们的代码更加优雅. 在我们的实际工作中,很多场景都会用到装饰器,比如记录一些日志.或者屏蔽一些不太合法的程序执行从而使我们的代码更加安全. 装饰器 什么是装饰器?虽然对这个次感到陌生,但是完全不需要担心. 首先,装饰器也是一种函数:只不过装饰器可以接收 函数 作为参

  • python装饰器-限制函数调用次数的方法(10s调用一次)

    这是博主最近一家大公司的面试题,写一个装饰器,限制函数每10s调用一次.当时是笔试的,只写了大概的代码,回来后温习了python装饰器的基础知识,把代码写完了.决定写篇博客记录下. 装饰器分为带参数得装饰器以及不带参数得装饰器. #不带参数的装饰器 @dec1 @dec2 def func(): ... #这个函数声明等价于 func = dec1(dec2(func)) #带参数的装饰器 @dec(some_args) def func(): ... #这个函数声明等价于 func = dec

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

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

  • python 通过类中一个方法获取另一个方法变量的实例

    1.在进行接口自动化测试过程中,经常出现接口数据的互相调用,如一些操作需要调用登陆之后返回的session或者token,下面同个简单的方法进行讲解 class A(): def a_add_b(self): a=10 b=20 self.S=a+b print (self.S) return self.S def c_add_ab(self): c=30 s=c+self.S print (s) t=A() t.a_add_b() t.c_add_ab() 运行之后,打印的结果为 30 60

  • 基于python 处理中文路径的终极解决方法

    1 .据说python3就没有这个问题了 2 .u'字符串' 代表是unicode格式的数据,路径最好写成这个格式,别直接跟字符串'字符串'这类数据相加,相加之后type就是str,这样就会存在解码失误的问题. 别直接跟字符串'字符串'这类数据相加 别直接跟字符串'字符串'这类数据相加 别直接跟字符串'字符串'这类数据相加 unicode类型别直接跟字符串'字符串'这类数据相加 说四遍 3 .有些读取的方式偏偏是要读取str类型的路径,不是unicode类型的路径,那么我们把这个str.enco

  • 基于python tkinter的点名小程序功能的实例代码

    代码如下所示: import datetime import json import os import random import tkinter as tk import openpyxl # 花名册文件名 excel_file_path = "花名册.xlsx"#需在当前目录创建对应花名册.xlsx # 工作表名 excel_sheet = "Sheet1" # 记录存储文件名 file_path = "name_record.json"

  • 基于Python实现配置热加载的方法详解

    目录 背景 如何实现 使用多进程实现配置热加载 使用signal信号量来实现热加载 采用multiprocessing.Event 来实现配置热加载 结语 背景 由于最近工作需求,需要在已有项目添加一个新功能,实现配置热加载的功能.所谓的配置热加载,也就是说当服务收到配置更新消息之后,我们不用重启服务就可以使用最新的配置去执行任务. 如何实现 下面我分别采用多进程.多线程.协程的方式去实现配置热加载. 使用多进程实现配置热加载 如果我们代码实现上使用多进程, 主进程1来更新配置并发送指令,任务的

随机推荐