Python高级用法:装饰器(decorator)

装饰器(decorator)

Python装饰器的作用是使函数包装与方法包装(一个函数,接受函数并返回其增强函数)变得更容易阅读和理解。最初的使用场景是在方法定义的开头能够将其定义为类方法或静态方法。
不使用装饰器的代码如下所示

类方法不用装饰器的写法

class WithoutDecorators:def some_static_method():print("this is static method")some_static_method = staticmethod(some_static_method)def some_class_method(cls):print("this is class method")some_class_method = classmethod(some_class_method)

函数不用装饰器的写法

def decorated_function():passdecorated_function = some_decorator(decorated_function)

如果用装饰器语法重写的话,代码会更简短,也更容易理解:

类方法使用装饰器的写法

class WithDecorators:@staticmethoddef some_static_method():print("this is static method")@classmethoddef some_class_method(cls):print("this is class method")

函数使用装饰器的写法

@some_decorator
def decorated_function():pass

装饰器通常是一个命名的对象,在装饰函数时接受单一参数,并返回另一个可调用(callable)对象,任何实现了__ call __方法的可调用对象都可以用作装饰器,它们返回的对象往往也不是简单的函数,而是实现了自己的__ call __方法的更复杂的类的实例。

任何函数都可以用作装饰器,Python没有规定装饰器的返回类型。所以使用单一参数但不返回可调用对象的函数用作装饰器,在语法上是完全有效的。如果调用这样装饰过的对象就会报错。

自定义装饰器

以函数形式创建

def mydecorator(function):def wrapped(*args, **kwargs):# 在调用原始函数之前,做点什么result = function(*args, **kwargs)# 在函数调用之后,做点什么,# 并返回结果return result# 返回wrapper作为装饰函数return wrapped

mydecorator传入的function是函数,在mydecorator中定义了一个函数wrapped,在wrapped函数中args和kwargs参数是原函数function的参数,装饰器使用wrapped来对函数进行修饰,所以装饰器返回的也是wrapped

以类的形式创建

class DecoratorAsClass:def __init__(self, function):self.function = functiondef __call__(self, *args, **kwargs):# 在调用原始函数之前,做点什么result = self.function(*args, **kwargs)# 在调用函数之后,做点什么,# 并返回结果return result

在这个类中self.function为需要修饰的函数,在__call__方法中定义对self.function的修饰

参数化装饰器

在实际代码中通常需要使用参数化的装饰器。如果用函数作为装饰器的话,需要用到第二层函数嵌套包装。

def repeat(number=3):def actual_decorator(function):def wrapper(*args, **kwargs):result = Nonefor _ in range(number):result = function(*args, **kwargs)return resultreturn wrapperreturn actual_decorator

在这里构建的是多次重复执行的装饰函数,number参数为重复次数,默认值是3

我们来测试一下参数化的装饰器

在这里插入图片描述

保存内省的装饰器

使用装饰器的常见问题是使用装饰器时不保存函数元数据,尤其是文档字符串和原始函数名。装饰器组合创建了一个新函数,并返回一个新对象,但却完全没有考虑原始函数的标识。这将会使得调试这样装饰过的函数更加困难,也会破坏可能用到的大多数自动生成文档的工具,因为无法访问原始的文档字符串和函数签名。我们来看一下细节。假设我们有一个虚设的(dummy)装饰器,仅有装饰作用,还有其他一些被装饰的函数:

def dummy_decorator(function):def wrapped(*args, **kwargs):"""包装函数内部文档。"""return function(*args, **kwargs)return wrapped@dummy_decorator
def function_with_important_docstring():"""这是我们想要保存的重要文档字符串。"""Pass

在这里插入图片描述

解决这个问题的正确方法是使用functools模块内置的wraps()装饰器

from functools import wrapsdef preserving_decorator(function):@wraps(function)def wrapped(*args, **kwargs):"""包装函数内部文档。"""return function(*args, **kwargs)return wrapped@preserving_decorator
def function_with_important_docstring():"""这是我们想要保存的重要文档字符串。"""pass

测试效果如下
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/315574.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue-响应式数据

一、ref创建基本类型的响应式数据 vue3可以使用ref、reactive去定义响应式数数据。 知识点汇总 使用ref需要先引入ref,import {ref} from vue在模板 template 中使用了添加ref 的响应式数据,变量的后面不用添加.value所有js代码里面,去操作r…

Nginx 反向代理负载均衡

Nginx 反向代理负载均衡 普通的负载均衡软件,如 LVS,其实现的功能只是对请求数据包的转发、传递,从负载均衡下的节点服务器来看,接收到的请求还是来自访问负载均衡器的客户端的真实用户;而反向代理就不一样了&#xf…

ArkTS开发实践

声明式UI基本概念 应用界面是由一个个页面组成,ArkTS是由ArkUI框架提供,用于以声明式开发范式开发界面的语言。 声明式UI构建页面的过程,其实是组合组件的过程,声明式UI的思想,主要体现在两个方面: 描述…

【python】Python 3.11不支持Tix库

Tix库主要用于扩展Tkinter,但是Python 3.11 Tkinter已经不再支持Tix库。Tix模块提供了一些额外的部件和功能,但现在这些功能已经整合到了Tkinter库中。 一、如果在Python 3.11中想要使用Tix库,但发现它不再被内置支持,可以尝试以…

十大排序的个人总结之——冒泡排序、插入排序

同样,这两几乎也是被淘汰了的算法,尽管它们是稳定的,但是时间复杂度没人喜欢,了解一下就好,没啥好说的,注意最后一句话就行了 一,冒泡排序 1. 算法步骤 共n-1趟,谁两敢冒泡就换了…

分布式定时任务Xxl_Job详细使用手册

看了很多网上的版本,思路描述的都不是很清晰,都只是几步操作就完成了,看效果,导致容易走入弯路(不排除是自己理解能力把),最开始以为是把admin模块集成到项目,后来测试了会&#xff…

如何本地快速部署Apache服务器并使用内网穿透工具实现公网访问内网服务

文章目录 前言1.Apache服务安装配置1.1 进入官网下载安装包1.2 Apache服务配置 2.安装cpolar内网穿透2.1 注册cpolar账号2.2 下载cpolar客户端 3. 获取远程桌面公网地址3.1 登录cpolar web ui管理界面3.2 创建公网地址 4. 固定公网地址 前言 Apache作为全球使用较高的Web服务器…

1-Linux-基础

文章目录 Linux基础知识操作系统基础知识Linux基础知识Linux系统的组成Linux系统图示Linux发行版 Linux基础命令Linux系统的目录结构目录结构对比:windows路径描述方式 Linux命令入门Linux命令通用格式入门命令示例:ls 目录切换【命令】路径:…

剑指offer

1、排序算法 0、排序算法分类 1、直接插入排序 基本思想 直接插入排序的基本思想是:将数组中的所有元素依次跟前面已经排好的元素相比较,如果选择的元素比已排序的 元素小,则交换,直到全部元素都比较过为止。 算法描述 1、从…

【SpringBoot3】1.SpringBoot入门的第一个完整小项目(新手保姆版+教会打包)

目录 1 SpringBoot简单介绍1.1 SpringBoot是什么1.2 主要优点1.3 术语1.3.1 starter(场景启动器) 1.4 官方文档 2 环境说明3 实现代码3.1 新建工程与模块3.2 加入依赖3.3 主程序文件3.4 业务代码3.5 运行测试3.6 部署打包3.7 命令行运行 1 SpringBoot简单…

Redis 除了用作缓存还能干吗?

Redis 除了用作缓存还能干吗? 文章出自 ByteByteGo 公众号,如有侵权,请联系立即删除 Redis 是一种内存键值数据库。它支持多种数据结构,如 String, Hash, List, Set 和 SortedSet。 01 缓存 Redis 的最常用的用例是缓存&#xff…

服务器监控软件夜莺部署(一)

文章目录 一、夜莺介绍1. 简介2. 相关网站 二、夜莺部署1. 部署架构2. Docker启动3. 配置数据源4. 内置仪表盘效果5. 时序指标效果 一、夜莺介绍 1. 简介 夜莺监控系统是一款专业的服务器监控软件,它可以帮助用户实时监测服务器的CPU、内存、磁盘利用率等。 夜莺监…