zoukankan      html  css  js  c++  java
  • Python装饰器的高级用法(翻译)

    原文地址
    https://www.codementor.io/python/tutorial/advanced-use-python-decorators-class-function

    介绍

    我写这篇文章的主要目的是介绍装饰器的高级用法。如果你对装饰器知之甚少,或者对本文讲到的知识点易混淆。我建议你复习下装饰器基础教程。
    本教程的目标是介绍装饰器的一些有趣的用法。特别是怎样在类中使用装饰器,怎样给装饰器传递额外的参数。

    装饰器 vs 装饰器模式

    Decorator模式是一个面向对象的设计模式,它允许动态地往现有的对象添加行为。当你装饰了一个对象,在某种程度上,你是在独立于同一个类的其他实例的基础上扩展其功能。
    Python装饰器不是装饰器模式的实现,它在函数、方法定义的时候添加功能,而不是在运行的时候添加。Decorator设计模式本身可以在Python中实现,因为Python是动态编程语言,所以没有必要这样做

    一个基础的装饰器

    这是装饰器的最简单例子,在继续往下面阅读之前请确保理解此段代码。如果你需要更多关于此代码的解释,请复习下基础装饰器教程。

    带参数的装饰器

    有时候带参数的装饰器会非常有用,这种技术经常用在函数注册中。在web框架Pyramid中经常有用到,例如:

    比方说,我们有一个用户可以登录并且可以和用户交互的GUI应用程序。用户和GUI界面的交互触发事件,导致Python函数执行。假设有许多使用该图形界面的用户,他们各自的权限级别差异很大,不同的功能执行需要不同的权限。比如,考虑以下功能:

    一种实现这些权限检查的方式是实现多个装饰器,比如

    但是,这太可怕了。这需要大量的复制粘贴,每个装饰器需要一个不同的名字,如果有任何关于权限检查的改变,每个装饰器都需要修改。就没有一个装饰器把以上三个装饰器的工作都干了的吗?
    为了解决此问题,我们需要一个返回装饰器的函数:

    尝试一下调用delete_usernew namepremium_checkpoint然后看看发生了什么。
    premium_checkpointdelete_user 产生了一个“permission denied”的异常,new_game执行正常。
    下面是带参数装饰的一般形式,和例子的使用:

    等价于:

    类装饰器

    装饰器不仅可以修饰函数,还可以对类进行装饰。比如说,我们有一个类,该类含有许多重要的方法,我们需要记录每一个方法执行的时间。我们可以使用上述的time_this装饰此类:

     

    此方法可以运行正常。但是在该类中存在许多多余的代码,如果我们想建立更多的类方法并且遗忘了装饰其中的一个方法,如果我们不想装饰该类中的方法了,会发生什么样的情况呢?这可能会存在出现认为错误的空间,如果写成这样会更有好:

    等价于:

    那么time_all_class_methods是怎么工作的呢?
    首先,我们需要采用一个类作为参数,然后返回一个类,我们也要知道返回的类的功能应该和原始类ImportantStuff功能一样。也就是说,我们仍然希望做重要的事情,我们希望记录下每个步骤发生的时间。我们写成这样:

    总结

    在此篇教程中,我们给大家展示了一些Python装饰器使用的技巧-我们介绍了怎么样把参数传递给装饰器,怎样装饰类。但是这仅仅是冰山一角。除了本文介绍的之外,还有其他好多装饰器的使用方法,我们甚至可以使用装饰器装饰装饰器(如果你有机会使用到它,这可能是一个做全面检查的好方法)。Python有一些内置的装饰器,比如:staticmethodclassmethod
    阅读完本文还需要学习什么呢?通常是没有比我在文章中展示的装饰器更复杂的了,如果你有兴趣学习更多关于改变类功能的方法,我建议您阅读下继承和OOP设计原则。或者你可以试试阅读一下元类。


    参考




  • 相关阅读:
    1012 最大公约数和最小公倍数问题 2001年NOIP全国联赛普及组
    数论笔记
    Codevs 1200 同余方程 2012年NOIP全国联赛提高组
    Codevs 1213 解的个数(exgcd)
    Qbxt 模拟赛&&day-8
    NOIP 模拟赛 那些年,我们学过的文化课 --致已退役的fqk神犇.
    OI路上 day -9
    P3178 [HAOI2015]树上操作
    P3979 遥远的国度
    P4092 [HEOI2016/TJOI2016]树
  • 原文地址:https://www.cnblogs.com/JetpropelledSnake/p/8908649.html
Copyright © 2011-2022 走看看