服务粉丝

我们一直在努力
当前位置:首页 > 情感 > 故事 >

独家 | 9个可以显著优化代码的Python内置装饰器

日期: 来源:数据派THU收集编辑:数据派THU

翻译:陈之炎

校对:赵茹萱

本文约2000字,建议阅读8分钟
本文介绍了精心挑选的9个函数装饰器,它将展示Python的优雅。

函数装饰器有事半功倍的力量。

Wallhaven 提供 图片

“简胜于繁。”

Python函数装饰器是“Python zen”哲学的最佳特性。

装饰器助力用更少、更简单的代码来实现复杂的逻辑,并在其他地方实现重用。

有许多很棒的内置Python装饰器使编码变得更为容易,只使用一行代码便可向当前的函数或类中添加复杂的函数。

行胜于言,接下来,来看看精心挑选的9个函数装饰器,它将展示Python的优雅。

1. @lru_cache:利用缓存提速程序

使用@lru_cache装饰器是提速Python函数最简易的方法。

此装饰器将函数的结果放入缓存,供后续具有相同参数的函数调用,无需再次执行具有相同参数的函数。

对于那些算力成本高昂或常用相同参数函数的调用特别有用。

来看看以下直观的示例:

上述程序用Python函数计算第n个Fibonacci数,这个函数非常耗时,当计算fibonacci(30)时,在递归过程中需要多次计算先前的Fibonacci数。

用@lru_cache装饰器来对它进行提速:

正如上述代码所示,使用@lru_cache装饰器后,可以在0.00002990秒内得到相同的结果,比先前的0.18129450秒快了不少。

@lru_cache装饰器有一个“最多结果数目”参数,该参数指定要在缓存中存储的最大结果数目。当缓存已满且需要存储新结果时,会将最近使用得最少的结果从缓存中删除,为新缓存腾出空间,称之为最近最不常用策略(LRU)。

默认情况下,将“最多结果数目”设为128。如果设为None,则禁用 LRU特性,缓存可以无约束地增长。

2. @total_ordering: 填充缺失排序方法的类装饰器

函数工具模块中的@total_sordeng装饰器为预定义Python类生成缺失比较方法。

下面为示例程序:

如上述代码所示,在学生类中没有对__ge__、__gt__和__le__方法进行定义,多亏有了@total_order装饰器,不同实例之间的比较结果均正确。

该装饰器的好处显而易见:

  • 可以使代码更干净,节省时间,因为无需编写全部比较方法。
  • 一些旧的类可能未充分定义比较方法,将@total_ordering装饰器添加到其中之后,后续的使用更加安全。

3. @contextmanager:定制的语境管理器

Python有一个语境管理器机制助力正确地管理资源。

大多数情况下,只需要使用with声明:


如上述代码所示,可以使用with语句打开文件,在写入之后将自动关闭。无需显式地调用f.close()函数来关闭该文件。

有时,需要为某些特定需求定义一个自定义的语境管理器,此时,@contextmanager装饰器便成为了我们的朋友。

例如,下述代码实现了一个简单的自定义语境管理器,它可以在文件打开或关闭时打印出相应的信息。


4. @property: 为Python类设置处理程序和设置程序

Getters和Setters是面向对象编程(OOP)中的重要概念。

对于类中的每个实例变量,getter方法返回其值,而setter方法设置或更新其值。鉴于此,Getters和Setters又分别称为Accessors和Mutators。

它们用于保护数据不会直接被意外访问或修改。

不同的OOP语言有不同的机制来定义获取器getters和setters。在Python中,可以简单地使用@property装饰器。

如上述示例所示,无法将分数变量设置为999,这是一个毫无意义的数字。因为@property装饰器的设置函数中限制了分数的可接受范围。

毫无疑问,添加这个setter可以成功地避免意外的错误和结果。

5. @cached_property:将方法的结果作为属性放入缓存

Python3.8的函数工具模块引入了一个新的功能强大的装饰器-@cached_property,它将类的方法转换为一个属性,计算出该属性的值之后,将其作为实例的普通属性放入缓存。

下面是这个示例:

在上述代码中,利用@cached_property来装饰局部方法,无需重复计算circle.area示例。

6. @classmethod:定义新的Python类方法

Python类中有三种方法类型:

  • Instancemethods(实例方法):绑定一个实例的方法,利用这种方法可以访问和修改实例数据。通过类的实例调用实例方法,通过self参数访问实例数据。
  • Classmethods(类方法):绑定一个类的方法,无法利用该方法修改实例数据。是调用类自身的一种方法,它将类作为第一个参数,通常将其命名为cls。
  • Staticmethods(静态方法):不绑定实例或类的方法。

可以将实例方法定义成普通的Python函数,它的第一个参数是自身;如果需要定义一个类方法,则需要使用@classmethod装饰器。

为了演示,下面的示例定义了一个类方法,可以用它来根据直径获得一个圆:


7. @staticmethod:为Python类定义静态方法

如前所述,静态方法不绑定到实例或类,仅仅因为它们在逻辑上属于那个类,才被包含进来。

静态方法通常用于执行一组相关任务的实用程序类中,如数学计算。通过将相关函数组织成类的静态方法,使代码变得更加有组织、更容易理解。

使用@staticmethod装饰器便可以定义一个静态方法,来看看下面这个例子:

8. @dataclass:用更少的代码定义专用类

@dataclass装饰器(在Python3.7中引入)可以自动为一个类生成几种专用的方法,如__init__、__repr__、__eq__、__lt__等。

因此,它可以节省大量编写这些基本方法的时间。如果一个类主要用于存储数据,那么@dataccass装饰器是最好的朋友。

为了进行演示,下面的示例只定义了一个名为Point类的两个数据字段,@dataclass装饰器就够用了:


9. @atexit.register:注册一个程序正常终止的函数

atexit模块的@register装饰器允许在Python解释器退出时执行一个函数。

该装饰器对于执行最终的任务非常有用,比如释放资源或说“再会”!

相关阅读

  • “孤勇者”蔡少伟:那只是别人眼中的我

  • 文 | 《中国科学报》 记者 胡珉琦
    蔡少伟 软件所供图少数者“我不怕坐冷板凳,怕的是连板凳都没有了。”这是国内约束求解研究人员的一句自嘲。
    求解器研究者、中科院软件研究
  • 使用TensorFlow Probability实现最大似然估计

  • 来源:DeepHub IMBA本文约2400字,建议阅读9分钟本文介绍了最大似然估计的过程,和TensorFlow Probability的实现。TensorFlow Probability是一个构建在TensorFlow之上的Python库
  • 势垒隧穿含时演化的Julia数值模拟

  • 文 | 杜炳毅 徐岩 摘 要:势垒隧穿是初等量子力学中的一个重要模型,但由于求解其波函数涉及超越方程,因此在许多初等量子力学教材中往往着重对透射系数的讲解,很少提及其波函数演
  • 回暖之后,国产医疗剧尚需破圈方法论

  • 在西医占据大多数医疗题材作品焦点的情况下,《促醒者》独辟蹊径地选择了以中医做切入,重点介绍了多个中医促醒的治疗方法,彰显出中医强大的价值与魅力。图为《促醒者》剧照彭侃

热门文章

  • 甘肃漳县:干部情撒麦田 助力夏粮归仓

  • 炎炎夏日,农事繁忙;麦穗飘香,颗粒归仓。近日,漳县马泉乡工会组织开展“干部情撒麦田,助力夏粮归仓”志愿服务行动,切实发挥广大干部职工的示范带动作用,扎实细

最新文章

  • 独家 | 9个可以显著优化代码的Python内置装饰器

  • 翻译:陈之炎 校对:赵茹萱本文约2000字,建议阅读8分钟本文介绍了精心挑选的9个函数装饰器,它将展示Python的优雅。函数装饰器有事半功倍的力量。Wallhaven 提供 图片“简胜于繁。
  • 春节年夜饭,一个人在云南过年:自己做饭不划算

  • 三年疫情结束,全国人民迎来了一个快乐的春节,今年春节可火爆了,很多北方人举家迁徙到南方过年,全国首选过年、气候最温和的不过云南跟海南两省。我是一个在路上六年旅行的背包客
  • 槐荫:文旅消费持续升温 游客“井喷式”增长

  • 随着兔年春节消费季大幕开启,槐荫便沉浸在浓郁的节日氛围之中,愉悦而祥和,各类文旅活动精彩纷呈,城市“西”引力不断释放。据统计,假期前三天,全区共接待游客数突破60万。与去年同