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():
	pass

decorated_function = some_decorator(decorated_function)

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

类方法使用装饰器的写法

class WithDecorators:
	@staticmethod
	def some_static_method():
		print("this is static method")

	@classmethod
	def 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 = function
	
	def __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 = None
			for _ in range(number):
				result = function(*args, **kwargs)
			return result
		return wrapper
	return 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 wraps

def preserving_decorator(function):
	@wraps(function)
	def wrapped(*args, **kwargs):
		"""包装函数内部文档。"""
		return function(*args, **kwargs)
	return wrapped

@preserving_decorator
def function_with_important_docstring():
	"""这是我们想要保存的重要文档字符串。"""
	pass

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Cesium特效-2023年汇总

1-3dTiles建筑实现随机贴图 使用3dTiles的customShader接口,在前端实现不同白模建筑贴不同的图片 2-淡入淡出的扩散雷达效果 在扩散雷的基础上,实现渐隐渐现的效果 3-不规则多边形的扩散效果 指定一个中心点,改变每个多边形的顶点位置来实现动…

如何做一个炫酷的Github个人简介(3DContribution)

文章目录 前言3D-Contrib第一步第二步第三步第四步第五步第六步 前言 最近放假了,毕设目前也不太想做,先搞一点小玩意玩玩,让自己的github看起来好看点。也顺便学学这个action是怎么个事。 3D-Contrib 先给大家看一下效果 我的个人主页&am…

坐标转换 | EXCEL中批量将经纬度坐标(EPSG:4326)转换为墨卡托坐标(EPSG:3857)

1 需求 坐标系概念: 经纬度坐标(EPSG:4326):WGS84坐标系(World Geodetic System 1984)是一种用于地球表面点的经纬度坐标系。它是美国国防部于1984年建立的,用于将全球地图上的点定位&#xff0…

普中STM32-PZ6806L开发板(HAL库函数实现-读取内部温度)

简介 主芯片STM32F103ZET6,读取内部温度其他知识 内部温度所在ADC通道 温度计算公式 V25跟Avg_Slope值 参考文档 stm32f103ze.pdf 电压计算公式 Vout Vref * (D / 2^n) 其中Vref代表参考电压, n为ADC的位数, D为ADC输入的数字信号。 实现…

Linux驱动学习—设备树及设备树下的platform总线

1、什么是设备树? 设备树是一种描述硬件资源的数据结构。他通过bootloader将硬件资源传给内核,使得内核和硬件资源 描述相对独立。 2、设备树的由来 2.1 平台总线的由来 要想了解为什么会有设备树,设备树是怎么来的,我们就要先…

网络安全—模拟IP代理隐藏身份

文章目录 网络拓扑安装使用代理服务器设置隐藏者设置 使用古老的ccproxy实现代理服务器,仅做实验用途,禁止做违法犯罪的事情,后果自负。 网络拓扑 均使用Windows Server 2003系统 Router 外网IP:使用NAT模式 IP DHCP自动分配或者…

提升软件质量与效率:UI自动化测试的重要性

在软件开发领域,UI自动化测试工具被广泛应用,其意义不仅仅体现在节省时间和资源上,更关系到软件质量的提升、团队效率的增加,以及用户体验的改善。本文将探讨使用UI自动化测试工具的重要性,以及它在软件开发生命周期中…

IDEA生成jar包

一、打开项目结构管理界面 英文版可以使用Ctrl Alt Shift S 打开 Project Structure 窗口 如下图 汉化idea 在设置中 tips:idea汉化包如果不能下载的话,可以手动下载安装 1、先确认自己安装的idea版本 2、来这里Chinese (Simplified) Language Pack…

一篇了解springboot3请求参数种类及接口测试

SpringBoot3数据请求: 原始数据请求: //原始方式RequestMapping("/simpleParam")public String simpleParam(HttpServletRequest request){//获取请求参数String name request.getParameter("name");String age request.getParame…

【备忘】今天写一下如何买免费证书

使用场景 使用微信支付宝支付转账时小游戏小程序接口开发时其它情况 开发中不可避免的会接触https,有的公司有运维去做这个事,有的是老板自己会搞https证书,咱多了解一项技术也是好事。 如何买证书 登录阿里云控制台,搜索ssl证…

transformers Trainer自定义optimizer和scheduler

1.需求 我自定义了一个evaluate方法,想在每一轮训练过后都执行一次。如果只是在TrainingArguments里设置warmup_steps100,那么每轮都会重置学习率,也就是每一轮开始的时候都会按照warmup刚开始的学习率进行训练,这就很头疼。 2.…

Android App从备案到上架全过程

不知道大家注意没有,最近几年来,新的移动App想要上架是会非常困难的,并且对于个人开发者和小企业几乎是难如登天,各种备案和审核。但是到底有多难,或许只有上架过的才会有所体会。 首先是目前各大应用市场陆续推出新的声明,各种备案截止日期到12月就要到最后期限责令整改…

MT8766安卓核心板规格参数_MTK8766核心板模块方案定制

MT8766安卓核心板:高性能、稳定可靠、集成度高的一体化解决方案 MT8766安卓核心板采用联发科MTK8766四核4G模块方案,是一款高度集成的安卓一体板。四核芯片架构,主频可达到2.0GHz,支持国内4G全网通。12nm制程工艺,支持…

全国计算机等级考试| 二级Python | 真题及解析(6)

全国计算机等级考试二级Python真题及解析(8)图文 一、选择题 1.python中表达式4**3=( )。 A.12 B.1 C.64 D.7 2.在Python中,通过( )函数查看字符的编码。 …

学生公寓安全用电管理系统应用案例

摘要:安全用电是学校公寓用电管理的首要任务,这就需要对一些恶性负载进行识别和控制,同时为了减少电工和后期管理人员的成本,引进了安全用电管理系统。本文在在描述了安全用电管理系统的工作原理和利用智能电表可实现的功能后,阐明…

B端产品经理学习-B端产品系统调研的工具

系统性调研目标的工具 系统性调研的目标 相对于背景调研,系统行调研是对公司可控因素(公司内部)和直接作用力(消费者、竞争者)进行的调研。系统性调研需要输出结论,为达成产品或公司的战略目标而制定行动的…

Dockerfile与DockerCompose

Docker的Image结构是怎样的? 镜像是将应用程序 及其需要的 系统函数库、环境、配置、依赖 打包而成。 镜像结构 入口( Entrypoint ) 镜像运行入口,一般是程序启动的脚本和参数 层( Layer ) 在BaseImage基…

Spring-IOC综述

文章迁移自语雀。 怎么查看spring的文档 ioc综述 说到spring的ioc,其实就是控制反转,为啥需要控制反转呢,其实是为了功能的增强,如果不用spring, 我们直接使用工厂方法,静态工厂方法, 都是是可以获取到对象的,但是如果需求变了,我们在类的生成时,添加了很多信息,使用工厂就不…

认真学SQL——MySQL入门之DQL多表查询

多表查询 本质: 把多个表通过主外键关联关系连接(join)合并成一个大表,再去查询 知识点: 外键 foreign key 外键概念: 在从表(多方)创建一个字段,引用主表(一方)的主键,对应的这个字段就是外键。 外键特点: 1:从表外键的值是对主表主键…

ubuntu安装vim报Package vim has no installation candidate

解决办法: sudo apt-get update sudo apt-get upgrade 然后再安装vim即可 sudo apt install vim fr:hunkxu