0

0

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

WBOY

WBOY

发布时间:2023-04-19 11:49:03

|

1657人浏览过

|

来源于51CTO.COM

转载

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

前言

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 = 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

3. @do_twice

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

英特尔AI工具
英特尔AI工具

英特尔AI与机器学习解决方案

下载

它可以用于测量两个不同迭代的性能。以 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: str
unit_price: float
stock: int = 0
 def 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):

另一种方法是使用元类!

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_unit
return decorator_use_unit
@use_unit("meters per second")
def average_speed(distance, duration):
return distance / duration

8. @singledispatch

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

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

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

@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)

相关文章

python速学教程(入门到精通)
python速学教程(入门到精通)

python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pip安装使用方法
pip安装使用方法

安装步骤:1、确保Python已经正确安装在您的计算机上;2、下载“get-pip.py”脚本;3、按下Win + R键,然后输入cmd并按下Enter键来打开命令行窗口;4、在命令行窗口中,使用cd命令切换到“get-pip.py”所在的目录;5、执行安装命令;6、验证安装结果即可。大家可以访问本专题下的文章,了解pip安装使用方法的更多内容。

339

2023.10.09

更新pip版本
更新pip版本

更新pip版本方法有使用pip自身更新、使用操作系统自带的包管理工具、使用python包管理工具、手动安装最新版本。想了解更多相关的内容,请阅读专题下面的文章。

416

2024.12.20

pip设置清华源
pip设置清华源

设置方法:1、打开终端或命令提示符窗口;2、运行“touch ~/.pip/pip.conf”命令创建一个名为pip的配置文件;3、打开pip.conf文件,然后添加“[global];index-url = https://pypi.tuna.tsinghua.edu.cn/simple”内容,这将把pip的镜像源设置为清华大学的镜像源;4、保存并关闭文件即可。

761

2024.12.23

python升级pip
python升级pip

本专题整合了python升级pip相关教程,阅读下面的文章了解更多详细内容。

349

2025.07.23

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

81

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

96

2025.09.18

python如何计算数的阶乘
python如何计算数的阶乘

方法:1、使用循环;2、使用递归;3、使用math模块;4、使用reduce函数。更多详细python如何计算数的阶乘的内容,可以阅读下面的文章。

171

2023.11.13

python求阶乘教程大全
python求阶乘教程大全

本专题整合了python求阶乘相关教程,阅读专题下面的文章了解更多详细内容。

11

2025.11.08

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.7万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号