关闭

python装饰器装饰类

标签: python装饰器装饰类
170人阅读 评论(0) 收藏 举报
分类:

装饰器可以用来像装饰函数一样装饰类(毕竟类也是可调用对象)
装饰类可以有多种用途。类装饰器可以和被装饰类的属性交互。一个类装饰器可以添加或增强属性,或者它可以修改类的API, 在类如何被定义和它的实例如何被使用之间提供区别。你可能 会问,添加或增强一个类的属性的合适做法不是通过子类么?通常,答案是这样。然而,在某些情况下,备选的方法可能更合适。例如,一个通用的可应用特性可能应用到你的应用的许多类上,在你的类结构的不同地方

举个例子,考虑类的这样一种特性,每个实例知道它是什么时候被实例化的,实例通过创建时间排序。这对许多不同的类有普遍的可应用性。
需要三个额外的属性—–实例化时间戳, __gt__ 和 __lt__ 方法。
有很多途径来进行添加. 你可以用一个类装饰器这样做:

import functools
import time

def sortable_by_creation_time(cls):
  """Given a class, augment the class to have its instances 
  be  sortable
  by the timestamp at which they were instantiated.
  """
  # Augment the class' original ‘__init__‘ method to alsostore a
  # ‘_created‘ attribute on the instance, which corresponds   
  #to when it
  # was instantiated.
  original_init = cls.__init__
  @functools.wraps(original_init)
  def new_init(self, *args, **kwargs):
    original_init(self, *args, **kwargs)
    self._created = time.time()
  cls.__init__ = new_init
  #Add ‘__lt__‘ and ‘__gt__‘ methods that return True or  
  # False based on
  # the created values in question.
  cls.__lt__ = lambda self, other: self._created < other._created
  cls.__gt__ = lambda self, other: self._created > other._created
  # Done; return the class object.
  return cls

这个装饰器做的第一件事情是保存了类的原始的__init__方法的副本。你不必担心这个类是否有这个方法。因为对象有__init__ 方法,这个属性的出现会有保证。下一步,创建一个新方法指派给__init__
这个方法首先调用原始的__init__然后做一部分额外工作, 保存实例的时间戳到 self._created.
值得注意的是这同前面的例子中的执行时包装代码非常相似的模式—-让一个函数包装另一个函数,它的主要职责是是运行被包装函数,但也会添加小片其它功能片段。
如果一个被@sortable_by_creation_time装饰的类定义了自己的__lt__ 和__gt__方法 ,那么这个装饰器会覆盖它们。
如果这个类没有意识到created是用来排序的,_created本身来讲就没什么用处。因此装饰器也添加 __lt_ 和 __gt__魔法方法.这些引起 < 和 > 操作符基于那些方法的结果返回True或者False。

这也会影响sorted和其它相似函数的行为
这是有必要的所有来让随便一个类的实例通过它们的实例化时间可排序。
这个装饰器可以被应用给任何类。包括许多有不相关的祖先的类。这有一个通过创建时间的可排序实例的简单类的例子

>>> @sortable_by_creation_time… class Sortable(object):
... def __init__(self, identifier):
... self.identifier = identifier… def _repr_(self):
... return self.identifier…
>>> first = Sortable('first')
>>> second = Sortable('second')
>>> third = Sortable('third')
>>>
>>> sortables = [second, first, third]
>>> sorted(sortables)
[first, second, third]

一定牢记,虽然装饰器可以解决一个问题,但不意味着它一定就是合适的解决方案。当说到这个例子,同样的事情能够通过使用一个“mixin,”或者只定义了合适的__init__, __lt__, 和 __gt__的很​小的类来完成。

一个使用了mixin的简单方法:

import time
class SortableByCreationTime(object):
  def __init__(self):
    self._created = time.time()
  def __lt__(self, other):
    return self._created < other._created
  def __gt__(self, other):
    return self._created > other._created

应用mixin给一个类可以通过使用Python的多继承来做到:

class MyClass(MySuperclass, SortableByCreationTime):
  pass

这个方式有不同的优点和缺点。一方面,它会毫不留情地犁过(plow over)由类或者它的超类(可能以后再阅读代码时,这会不太明显,装饰器正在“修理”两个方法)定义的__lt__ 和 __gt__方法。
另一方面,可能很容易陷入一种境地,由SortableByCreationTime提供的__init__方法不会运行
如果MyClass 或者
MySuperclass 或者任何在MySuperclass的祖先中中定义了一个__init__方法 ,这个方法会胜出。反转类的顺序无法解决这个问题;

相反,装饰器会很好地处理__init__的情况,只需要增强被装饰类的__init__方法的影响,否则不做任何变动。

哪种情况是正确的? 视情况而定。

0
0
查看评论

Python——编写类装饰器

本文介绍了Python编写类装饰器的几个示例,包括,单体类、跟踪对象接口以及实现私有属性private
  • ggGavin
  • ggGavin
  • 2016-03-18 15:40
  • 9242

Python 装饰器装饰类中的方法

title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] category: ['Python'] --- ...
  • hesi9555
  • hesi9555
  • 2017-04-18 09:54
  • 2256

python装饰器简介---这一篇也许就够了

Python装饰器(decorator)是在程序开发中经常使用到的功能,合理使用装饰器,能让我们的程序如虎添翼。 装饰器引入初期及问题诞生假如现在在一个公司,有A B C三个业务部门,还有S一个基础服务部门,目前呢,S部门提供了两个函数,供其他部门调用,函数如下:def f1(): prin...
  • u010358168
  • u010358168
  • 2017-09-01 14:57
  • 304

Python3学习(24)--内置装饰器@property

@property 前面我们学过装饰器,我们知道,装饰器的作用就是用来扩展函数的,当然前面我们介绍的装饰器,都是我们自己定义的,格式如下: @decoretor def func(*args,**others)        ...
  • Appleyk
  • Appleyk
  • 2017-09-05 12:40
  • 3351

装饰器之类装饰器

外部的方法至今都玩过了,现在来思索一下的方法这么装饰 类方法修饰器 类的方法唯一的特殊点在于,self内部是可以调用的,但是在外部却是隐藏的,那这个怎么搞 为求稳妥,先定参修饰一个def godme(fun): def __godme(self,message): pr...
  • wait_for_eva
  • wait_for_eva
  • 2017-09-20 00:11
  • 252

python中装饰器的使用和类装饰器在类中方法的使用

前面一遍讲述了装饰器的基本知识,正好最近有个系统需要进行权限控制,那么我们就实例分析下装饰器的使用。装饰器是一个面向切面编程,主要作用就是权限控制,插入日志,性能测试,事务处理,缓存等。 对于重要的系统我们仅仅控制登录是不够的,对于固定人员使用到的系统我们还是要进行权限的细分。下面是bollte...
  • nextdoor6
  • nextdoor6
  • 2016-12-07 10:26
  • 2476

java常用类解析三:IO系统装饰类

java IO系统采用装饰器模式,用一些装饰类来装饰输入输出来,提供更强大的IO操作 FilterInputStream(FilterOutputStream)继承自InputStream(Outputstream) 常用装饰类(都继承自FilterInputStream)
  • Touch_2011
  • Touch_2011
  • 2011-10-07 17:03
  • 3759

装饰模式和AOP

3.3  装饰模式和AOP         装饰模式和AOP在思想上有共同之处。可能有些朋友还不太了解AOP,下面先简单介绍一下AOP的基础知识。 1:什么是AOP——面向方面编程   &#...
  • weiyong1999
  • weiyong1999
  • 2014-02-28 14:59
  • 2549

装饰模式(DecoratorPattern)与继承(Extends)的区别

装饰模式(DecoratorPattern)与继承(Extends)的区别 为什么要使用装饰模式呢? 在项目开发的过程中,当客户提出了个新的需求(这个新的需求需要对我们的某个类进行改动),为了这个新的需求,当然我们会想到去扩展某个类,扩展类的功能我们可以使用继承和装饰来达到我们的目的。那到底我们是...
  • ghgzczxcvxv
  • ghgzczxcvxv
  • 2015-02-03 13:08
  • 1431

9-5在类中定义装饰器

# -*- coding:utf-8 -*-""" 实际案例: 实现一个能将函数调用信息记录到日志的装饰器: 1.把每次函数的调用时间,执行时间.调用次数写入日志. 2.可以对被装饰函数分组,调用信息记录到不同日志. 3.动态修改参数,比如日志格式. 4.动态打开关闭日...
  • xiaochonghao
  • xiaochonghao
  • 2017-03-24 09:54
  • 611
    个人资料
    • 访问:9561次
    • 积分:359
    • 等级:
    • 排名:千里之外
    • 原创:13篇
    • 转载:5篇
    • 译文:14篇
    • 评论:3条