Python 编程语言的一大优点是它把所有功能都打包到一个小包中,这些功能非常有用。许多特性可以完全改变 Python 代码的功能,这使得该语言更加灵活。如果使用得当,其中一些功能可以有效缩短编写程序所需的时间。实现这些目标的一个很好的例子是 Python 的装饰器。

装饰器(decorators)是一个可以用于改变一个Python函数对象行为的函数。它们可以应用于类和函数,可以做很多非常有趣的事情!装饰器可以用来缩短代码、加速代码并彻底改变代码在 Python 中的行为方式。不用说,这当然可以派上用场!今天我想炫耀一些我认为值得一试的装饰器。有很多装饰器,但我选择了一些我认为具有最酷功能的装饰器。

1. @lru_cache

此列表中的第一个装饰器来自 functools 模块。该模块包含在标准库中,非常易于使用。它还包含比这个装饰器更酷的功能,但这个装饰器肯定是我最喜欢的。此装饰器可用于使用缓存加速函数的连续运行。当然,这应该在使用时记住一些关于缓存的注意事项,但在通用使用情况下,大多数时候这个装饰器是值得使用的。

能够用一个简单的装饰器来加速代码是非常棒的。可以从这样的装饰器中受益的函数的一个很好的例子是递归函数,例如计算阶乘的函数:

def factorial(n):return n * factorial(n-1) if n else 1

递归在计算时间上可能非常困难,但添加此装饰器有助于显着加快此函数的连续运行速度。

@lru_cache
def factorial(n): return n * factorial(n-1) if n else 1

现在每当我们运行这个函数时,前几个阶乘计算将被保存到缓存中。因此,下次我们调用该函数时,我们只需要计算我们之前使用的阶乘之后的阶乘。当然,并不是所有的阶乘计算都会被保存,但是很容易理解为什么这个装饰器的一个很好的应用程序来加速一些自然很慢的代码。

2. @jit

JIT 是即时编译(Just In Time)的缩写。通常每当我们在 Python 中运行一些代码时,发生的第一件事就是编译。这种编译会产生一些开销,因为类型被分配了内存,并存储为未分配但已命名的别名。使用即时编译,我们在执行时才进行编译。在很多方面,我们可以将其视为类似于并行计算的东西,其中 Python 解释器同时处理两件事以节省一些时间。

Numba JIT 编译器因将这一概念提供到 Python 中而闻名。与@lru_cache 类似,可以非常轻松地调用此装饰器,并立即提高代码的性能。Numba 包提供了 jit 装饰器,它使运行更密集的软件变得更加容易,而不必进入 C。

以下案例使用@jit装饰器加速蒙特卡洛方法计算。

from numba import jit
import random@jit(nopython=True)
def monte_carlo_pi(nsamples):acc = 0for i in range(nsamples):x = random.random()y = random.random()if (x ** 2 + y ** 2) < 1.0:acc += 1return 4.0 * acc / nsamples

3. @do_twice

do_twice 装饰器的功能与它的名字差不多。此装饰器可用于通过一次调用运行两次函数。这当然有一些用途,我发现它对调试特别有用。它可以用于测量两个不同迭代的性能。以 Functools 为例,我们可以让一个函数运行两次,以检查是否有改进。该函数由 Python 中的装饰器模块提供,该模块位于标准库中。

from decorators import do_twice
@do_twice
def timerfunc():%timeit factorial(15)

4. @count_calls

count_calls 装饰器可用于提供有关函数在软件中使用多少次的信息。像 do_twice 一样,这当然可以在调试时派上用场。当添加到给定的函数时,我们将收到一个输出,告诉我们该函数每次运行时已经运行了多少次。这个装饰器也在标准库的装饰器模块中。

from decorators import count_calls
@count_calls
def function_example():print("Hello World!")function_example()
function_example()
function_example()

5. @dataclass

为了节省编写类的时间,我一直使用的最好的装饰器之一是@dataclass装饰器。这个装饰器可用于快速编写类中常见的标准方法,这些方法通常会在我们编写的类中找到。

这个装饰器来自 dataclass 模块。这个模块也在标准库中,所以不需要PIP来尝试这个例子!

from dataclasses import dataclass@dataclass
class Food:name: strunit_price: floatstock: int = 0def stock_value(self) -> float:return(self.stock * self.unit_price)

这段代码将自动创建一个初始化函数 __init__(),其中包含填充类中数据所需的位置参数。它们也将自动提供给 self,因此无需编写一个很长的函数来将一些数据参数放入类中。

6. @singleton

为了理解单例装饰器的用途,我们首先需要了解单例(singleton)是什么。从某种意义上说,单例是全局变量类型的一个版本。这意味着类型被定义为只存在一次。尽管这些在 C++ 等语言中很常见,但在 Python 中却很少见到。使用单例,我们可以创建一个只使用一次的类并改变类,而不是通过初始化来构造新的类型。

通常,单例装饰器是由用户自己编写的,实际上并不是导入的。这是因为单例仍然是对我们单例装饰器中提供的模板的引用。我们可以命名一个单例函数并编写一个包装器,以便在我们的类上使用这个装饰器:

def singleton(cls):instances = {}def wrapper(*args, **kwargs):if cls not in instances:instances[cls] = cls(*args, **kwargs)return instances[cls]return wrapper@singleton
class cls:def func(self):

解决此问题的另一种方法是使用元类。

  • Python进阶:一步步理解Python中的元类metaclass

7. @use_unit

在科学计算中经常派上用场的一种装饰器是 @use_unit 装饰器。此装饰器可用于更改返回结果的表示单位。这对于那些不想在数据中添加度量单位但仍希望人们知道这些单位是什么的人很有用。这个装饰器也不是在任何模块中真正可用,但它是非常常见的,对科学应用程序非常有用。

def use_unit(unit):"""Have a function return a Quantity with given unit"""use_unit.ureg = pint.UnitRegistry()def decorator_use_unit(func):@functools.wraps(func)def wrapper_use_unit(*args, **kwargs):value = func(*args, **kwargs)return value * use_unit.ureg(unit)return wrapper_use_unitreturn decorator_use_unit@use_unit("meters per second")
def average_speed(distance, duration):return distance / duration

8. @singledispatch

Functools 凭借非常有用的@singledispatch 装饰器再次在此列表中脱颖而出。单调度是一种编程技术,在许多编程语言中都很常见,因为它是一种非常棒的编程方式。虽然我更喜欢多调度,但我认为单调度可以在很多方面扮演相同的角色。

这个装饰器使得在 Python 中使用多类型数据变得更加容易, 尤其当我们希望通过同一方法传递多种类型数据时,情况更是如此。我在我的 FuncTools 文章中写了更多关于这个的内容,所以如果你对使用单一调度方法感兴趣,我推荐它。

@singledispatch
def fun(arg, verbose=False):if verbose:print("Let me just say,", end=" ")print(arg)@fun.register
def _(arg: int, verbose=False):if verbose:print("Strength in numbers, eh?", end=" ")print(arg)@fun.register
def _(arg: list, verbose=False):if verbose:print("Enumerate this:")for i, elem in enumerate(arg):print(i, elem)

文章来源:https://towardsdatascience.com/10-fabulous-python-decorators-ab674a732871

原作:埃米特·布德罗 翻译:大江狗

推荐阅读

一文看懂Python协程asyncio模块的演变及高级用法

一文看懂Python系列之装饰器(decorator)(工作面试必读)

Django基础(26): 常用装饰器应用场景及正确使用方法

推荐8个炫酷的 Python 装饰器!相关推荐

  1. 推荐 8 个炫酷的 Python 装饰器

    前言 Python 编程语言的一大优点是它把所有功能都打包到一个小包中,这些功能非常有用. 许多特性可以完全改变 Python 代码的功能,这使得该语言更加灵活.如果使用得当,其中一些功能可以有效缩短 ...

  2. 超棒!推荐八个炫酷的 Python 装饰器!

    Python 编程语言的一大优点是它把所有功能都打包到一个小包中,这些功能非常有用. 许多特性可以完全改变 Python 代码的功能,这使得该语言更加灵活.如果使用得当,其中一些功能可以有效缩短编写程 ...

  3. python炫酷特效代码_推荐几个炫酷的 Python 开源项目

    推荐几个炫酷的 Python 开源项目 项目一: Supervisor 简介: Supervisor 是实际企 业常用的一款 Linux/Unix 系统下的一个进程管理工具, 基于 Python 开发 ...

  4. 推荐几个炫酷的Python开源项目

    项目一: Supervisor 简介:Supervisor是实际企业常用的一款 Linux/Unix 系统下的一个进程管理工具,基于Python开发,可以很方便的监听.启动.停止.重启一个或多个进程, ...

  5. 【全网最全的博客美化系列教程】06.推荐和反对炫酷样式的实现

    全网最全的博客美化系列教程相关文章目录 [全网最全的博客美化系列教程]01.添加Github项目链接 [全网最全的博客美化系列教程]02.添加QQ交谈链接 [全网最全的博客美化系列教程]03.给博客添 ...

  6. 【博客美化】01.推荐和反对炫酷样式

    博客园美化相关文章目录: [博客美化]01.推荐和反对炫酷样式 [博客美化]02.公告栏显示个性化时间 [博客美化]03.分享按钮 [博客美化]04.自定义地址栏logo [博客美化]05.添加Git ...

  7. python装饰器-python装饰器简介---这一篇也许就够了(推荐)

    Python装饰器(decorator)是在程序开发中经常使用到的功能,合理使用装饰器,能让我们的程序如虎添翼. 装饰器引入 初期及问题诞生 假如现在在一个公司,有A B C三个业务部门,还有S一个基 ...

  8. 10个美妙的Python装饰器

    10个美妙的Python装饰器 对Python编程语言中我最喜欢的一些装饰器的概述. 简介 关于Python编程语言的伟大之处在于,它在一个小包里装了所有的功能,这些功能非常有用.很多特性可以完全改变 ...

  9. python装饰器原理-Python装饰器原理与用法分析

    这篇文章主要介绍了Python装饰器原理与用法,结合实例形式分析了Python装饰器的概念.原理.使用方法及相关操作注意事项,需要的朋友可以参考下 本文实例讲述了Python装饰器原理与用法.分享给大 ...

最新文章

  1. SpringBoot+Vue实现请求后台获取Base64编码的图片验证码并使用Redis缓存实现2分钟内有效
  2. JavaMelody开源系统性能监控软件:
  3. 哥谈的是语言,不是寂寞
  4. 浮动在IE6,7下的一些问题
  5. 05-Elasticsearch官网译文(1)
  6. 【LeetCode】汉明距离(Hamming Distance)
  7. 阿里云获中国互联网网络安全威胁治理联盟特别贡献奖
  8. VIVADO常见警告、错误及解决方法
  9. 超详细的Python安装和环境搭建教程
  10. 下一步工作应该怎样开展
  11. Linux中将4块10T新硬盘合并成一个,挂载到Resource目录下
  12. Ansys Lumerical | 行波 Mach-Zehnder 调制器仿真分析
  13. pecl 安装指定版本swoole
  14. cpu上干硅脂怎么清理_如何去除CPU上原来的硅脂
  15. 截图/贴图神器—Snipaste,下载地址
  16. WinRAR压缩解压文件
  17. Discuz 服务器重启后无法访问
  18. 巯基吡啶PEG巯基吡啶,OPSS-PEG-OPSS
  19. mysql计算两个月份之间的差值_MySQL计算两个日期相差的天数、月数、年数
  20. 电脑通过豌豆荚连接手机或者平板不成功,豌豆荚版本6.8.*

热门文章

  1. 黑白色老照片一键上色在线工具,让老照片漂亮起来
  2. 【导航业务架构】Autoware和Apollo自动驾驶系统的对比
  3. 申通快递机器人上岗_申通快递机器人效率惊人:70%人工下岗
  4. 数字化转型:信息化是过去,数字化是现在,智能化是未来
  5. Java中快速掌握正则表达式
  6. JS——图片变清晰(简易版刮刮乐)
  7. Charles抓Https
  8. android.view.InflateException: Binary XML file 解决方
  9. 【移动端适配二】H5移动端适配屏幕安全区(ios和android)
  10. 中国智慧农业发展研究报告 附下载