前言

Python 编程语言的一大优点是它把所有功能都打包到一个小包中,这些功能非常有用。

许多特性可以完全改变 Python 代码的功能,这使得该语言更加灵活。如果使用得当,其中一些功能可以有效缩短编写程序所需的时间。

实现这些目标的一个很好的例子是 Python 的装饰器。

00 装饰器

装饰器(decorators)是一个可以用于改变一个 Python 函数对象行为的函数。它们可以应用于类和函数,可以做很多非常有趣的事情!

装饰器可以用来缩短代码、加速代码并彻底改变代码在 Python 中的行为方式。

不用说,这当然可以派上用场!今天我想炫耀一些我认为值得一试的装饰器。

有很多装饰器,但我选择了一些我认为具有最酷功能的装饰器。

01 @lru_cache

此列表中的第一个装饰器来自 functools 模块。

该模块包含在标准库中,非常易于使用。它还包含比这个装饰器更酷的功能,但这个装饰器肯定是我最喜欢的。

此装饰器可用于使用缓存加速函数的连续运行。当然,这应该在使用时记住一些关于缓存的注意事项,但在通用使用情况下,大多数时候这个装饰器是值得使用的。

能够用一个简单的装饰器来加速代码是非常棒的。

可以从这样的装饰器中受益的函数的一个很好的例子是递归函数,例如计算阶乘的函数:

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

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

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

现在每当我们运行这个函数时,前几个阶乘计算将被保存到缓存中。

因此,下次我们调用该函数时,我们只需要计算我们之前使用的阶乘之后的阶乘。

当然,并不是所有的阶乘计算都会被保存,但是很容易理解为什么这个装饰器的一个很好的应用程序来加速一些自然很慢的代码。

02 @jit

JIT 是即时编译(Just In Time)的缩写。通常每当我们在 Python 中运行一些代码时,发生的第一件事就是编译。

这种编译会产生一些开销,因为类型被分配了内存,并存储为未分配但已命名的别名。使用即时编译,我们在执行时才进行编译。

在很多方面,我们可以将其视为类似于并行计算的东西,其中 Python 解释器同时处理两件事以节省一些时间。

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

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

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

03 @do_twice

do_twice 装饰器的功能与它的名字差不多。此装饰器可用于通过一次调用运行两次函数。这当然有一些用途,我发现它对调试特别有用。

它可以用于测量两个不同迭代的性能。以 Functools 为例,我们可以让一个函数运行两次,以检查是否有改进。该函数由 Python 中的装饰器模块提供,该模块位于标准库中。

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

04 @count_calls

count_calls 装饰器可用于提供有关函数在软件中使用多少次的信息。

像 do_twice 一样,这当然可以在调试时派上用场。

当添加到给定的函数时,我们将收到一个输出,告诉我们该函数每次运行时已经运行了多少次。这个装饰器也在标准库的装饰器模块中。

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

05 @dataclass

为了节省编写类的时间,我一直使用的最好的装饰器之一是@dataclass 装饰器。

这个装饰器可用于快速编写类中常见的标准方法,这些方法通常会在我们编写的类中找到。

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

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

这段代码将自动创建一个初始化函数 init,其中包含填充类中数据所需的位置参数。

它们也将自动提供给 self,因此无需编写一个很长的函数来将一些数据参数放入类中。

06 @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
@singletonclass cls:def func(self):

另一种方法是使用元类!

07 @use_unit

在科学计算中经常派上用场的一种装饰器是 @use_unit 装饰器。

此装饰器可用于更改返回结果的表示单位。这对于那些不想在数据中添加度量单位但仍希望人们知道这些单位是什么的人很有用。

这个装饰器也不是在任何模块中真正可用,但它是非常常见的,对科学应用程序非常有用。

def use_unit(unit):"""Have a function return a Quantity with given unit"""use_unit.ureg = pint.UnitRegistrydef 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

08 @singledispatch

Functools 凭借非常有用的@singledispatch 装饰器再次在此列表中脱颖而出。

单调度是一种编程技术,在许多编程语言中都很常见,因为它是一种非常棒的编程方式。虽然我更喜欢多调度,但我认为单调度可以在很多方面扮演相同的角色。

这个装饰器使得在 Python 中使用多类型数据变得更加容易, 尤其当我们希望通过同一方法传递多种类型数据时,情况更是如此。

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

最后祝大家天天进步!学习Python最重要的就是心态。我们在学习过程中必然会遇到很多难题,可能自己想破脑袋都无法解决。这都是正常的,千万别急着否定自己,怀疑自己。如果大家在刚开始学习中遇到困难,想找一个python学习交流环境,可以加入我们,领取学习资料,一起讨论

推荐 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. C++中的基本数据类型介绍
  2. SAP RETAIL 补货类型RF之初探 I
  3. 网络推广过程中切忌要注意的问题
  4. win2003 服务器超出最大连接+强制重启服务器(方法)
  5. 【AI学院】老司机手把手带学言有三的经典书籍《深度学习之图像识别》,需要的赶紧上车吧...
  6. AIProCon在线大会笔记之阿里达摩院司罗:为商业搭建语言桥梁
  7. [转]张孟苏考上的不是大学
  8. .NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法
  9. CAlayer层的属性
  10. C语言——冒泡排序法
  11. python赋值浅拷贝和深拷贝的区别_浅拷贝、深拷贝和普通赋值操作有什么区别?...
  12. 每个特征图1各因子和一个偏置_nlp中的概率图模型
  13. ubuntu远程桌面连接windows系统
  14. 英特尔中国研究院院长宋继强:摩尔定律的经济效益仍在继续
  15. 深度学习之RNN循环神经网络(理论+图解+Python代码部分)
  16. matlab线性同余发生器,用MATLAB进行随机数模拟--线性同余法
  17. 思科模拟器Cisco Packet Tracer 7.3 for Mac 安装和汉化(带安装包和汉化包)
  18. 《白帽子讲web安全》笔记
  19. 【码住收藏】软件测试报告模板范文来了——优秀测试报告模板流程
  20. 修改Oracle系统管理员密码

热门文章

  1. select() 函数
  2. 如何将彩色图片改成黑白色?
  3. 浅谈电力物联网在智能配电系统应用
  4. 关于 Intel CPU 和Iris Xe Graphics的报告问题
  5. 打印机每次都要重新连接后才能打印,解决办法
  6. python爬虫基础-http/https协议
  7. 【英语:语法基础】B7.核心语法-英文的基础时态
  8. Unity3D多屏幕显示时,第二屏幕的按钮无法正常点击
  9. 易语言多线程大漠多线程初始化COM库
  10. python关键字from_from关键字和Python中的示例