装饰器 篇

文章目录

  • 装饰器
  • classmethod()
  • property()
  • staticmethod()

装饰器

在Python中,装饰器(Decorator)是一个高级功能,它允许你在不修改函数或类本身代码的情况下,给函数或类动态地添加额外的功能。装饰器本质上是一个接受函数作为参数的高阶函数,并返回一个新的函数。

装饰器的语法使用 @ 符号,后面跟着装饰器的名称,然后是一个函数定义。装饰器通常用于添加日志、性能分析、事务处理、缓存、权限校验等功能。

下面是一个简单的装饰器示例,用于计算函数的执行时间:

import timedef timer_decorator(func):def wrapper(*args, **kwargs):start_time = time.time()result = func(*args, **kwargs)end_time = time.time()print(f"Function {func.__name__} took {end_time - start_time} seconds to execute.")return resultreturn wrapper@timer_decorator
def my_function():time.sleep(1)  # 假设这是一个耗时的操作print("Function executed!")my_function()

在这个例子中,timer_decorator 是一个装饰器函数,它接受一个函数作为参数(在这个例子中是 my_function),然后定义了一个新的函数 wrapper。wrapper 函数记录了 my_function 的执行时间,并在执行完成后打印出来。最后,timer_decorator 返回 wrapper 函数,这个返回的函数替代了原来的 my_function。

使用 @timer_decorator 语法,我们告诉Python在定义 my_function 之后立即应用 timer_decorator。这样,当我们调用 my_function 时,实际上是在调用 wrapper 函数。

装饰器可以更加复杂,并且可以接受参数,以提供更大的灵活性。它们也可以用于类方法,以装饰类的方法。

需要注意的是,装饰器不应该修改被装饰函数的源代码或调用方式,它们应该保持函数或方法的签名不变,只是简单地添加额外的行为。

classmethod()

classmethod 是Python内置的一个装饰器,用于指示一个方法应当作为类方法而不是实例方法。类方法属于类本身,而不是类的任何特定实例。这意味着类方法可以通过类名直接调用,也可以通过类的实例调用,但不管如何调用,类方法的第一个参数总是类本身,通常命名为 cls。

类方法通常用于执行与类相关但不依赖于类实例的任务,例如创建类的实例、修改类属性或访问与类关联的静态资源。

下面详细讲解 classmethod 装饰器:
定义类方法

使用 @classmethod 装饰器来定义类方法。例如:

class MyClass:@classmethoddef my_class_method(cls, arg1, arg2):print(f"Calling class method of {cls.__name__} with arguments {arg1} and {arg2}")# 调用类方法
MyClass.my_class_method("hello", "world")  # 使用类名调用# 或者
obj = MyClass()
obj.my_class_method("hello", "world")  # 使用实例调用

在这个例子中,my_class_method 是一个类方法。无论我们是使用 MyClass 类名还是它的一个实例 obj 来调用这个方法,cls 参数总是接收 MyClass 类本身。
类方法的用途

类方法通常用于以下几种情况:

工厂方法:创建并返回类的实例。
class MyClass:@classmethoddef from_string(cls, string_representation):# 解析 string_representation 并创建类的实例return cls(parsed_data)
修改类属性:类方法可以修改类级别的状态。
class MyClass:count = 0@classmethoddef increment_count(cls):cls.count += 1
访问类级别的资源:类方法可以访问与类关联的静态资源或配置。
class MyClassFactory:CLASSES = {"A": MyClassA, "B": MyClassB}@classmethoddef get_class(cls, class_name):return cls.CLASSES.get(class_name)

类方法与实例方法的比较

  • 实例方法:第一个参数是 self,代表类的实例。实例方法必须通过类的实例来调用,并且 self 参数会自动绑定到调用该方法的实例上。
class MyClass:def my_instance_method(self, arg):print(f"Calling instance method of {self.__class__.__name__} with argument {arg}")
  • 类方法:第一个参数是 cls,代表类本身。类方法可以通过类名或类的实例来调用,cls 参数会自动绑定到类上。

总的来说,classmethod 装饰器使得你能够定义一种特殊类型的方法,即类方法,它们与实例方法不同,因为它们与类本身而不是类的实例相关联。

property()

在Python中,property()是一个内置函数,用于将一个方法变成属性getter。当你访问这个属性时,实际上是在调用这个方法。此外,property()还可以接受setter和deleter方法,从而允许你对属性进行赋值和删除操作。

使用property()可以使得类更加面向对象,它允许你像访问数据属性一样来访问方法,同时你还可以控制对这个“属性”的读取、赋值和删除操作。

下面是property()的基本用法:

class Circle:def __init__(self, radius):self._radius = radius@propertydef radius(self):"""Getter for radius."""return self._radius@radius.setterdef radius(self, value):"""Setter for radius."""if value < 0:raise ValueError("Radius cannot be negative!")self._radius = value@radius.deleterdef radius(self):"""Deleter for radius."""del self._radius# 使用property的示例
c = Circle(5)
print(c.radius)  # 调用getter,输出: 5c.radius = 10  # 调用setter
print(c.radius)  # 再次调用getter,输出: 10del c.radius  # 调用deleter
# 如果再次访问c.radius,将会抛出一个AttributeError,因为_radius已经被删除了

在上面的例子中,radius是一个属性,但实际上它背后有三个方法:

  • radius(self): 这是一个getter方法,用于读取_radius的值。
  • radius(self, value): 这是一个setter方法,用于设置_radius的值,并且在设置之前进行了一些验证(例如,确保半径不是负数)。
  • radius(self): 这是一个deleter方法,用于删除_radius。

通过property()装饰器,你可以将这三个方法合并成一个单一的属性,从而提供更简洁、更面向对象的接口。

注意,如果你只定义了一个getter方法,而没有定义setter或deleter方法,那么该属性就是只读的。如果你定义了setter方法,那么该属性就是可写的。如果你定义了deleter方法,那么该属性就可以被删除。

使用property()的一个主要好处是,你可以在getter、setter和deleter方法中添加额外的逻辑,例如验证、计算或通知其他属性等,而用户在使用这个属性时完全不需要知道这些背后的复杂性。

staticmethod()

staticmethod 是Python中的一个装饰器,用于指示一个方法应当作为静态方法而不是实例方法或类方法12。

静态方法的特点是:

不需要传递实例参数和类参数:静态方法既不需要传递 self(实例参数)也不需要传递 cls(类参数)12。
无法访问实例属性和方法:由于静态方法不与任何实例或类关联,因此它不能访问实例的属性或方法,也不能访问类的属性或方法(除非这些属性或方法是作为全局变量或函数参数传递的)12。
通过类名调用:静态方法可以通过类名直接调用,而不需要创建类的实例12。

静态方法通常用于实现与类相关但不依赖于类实例或类状态的函数,例如工具函数或辅助函数2。

下面是一个使用 staticmethod 的例子:

class MyClass:@staticmethoddef my_static_method(arg1, arg2):print(f"Calling static method with arguments {arg1} and {arg2}")# 调用静态方法
MyClass.my_static_method("hello", "world")# 由于静态方法不依赖于实例,因此不能通过实例调用(但技术上仍然可以这样做)
obj = MyClass()
obj.my_static_method("hello", "world")  # 这将正常工作,但不是一个好的做法

在这个例子中,my_static_method 是一个静态方法,它不接受 self 或 cls 参数,并且可以通过 MyClass 类名直接调用。尽管可以通过类的实例调用静态方法,但这通常不是一个好的做法,因为它违反了静态方法的初衷。

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

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

相关文章

Python学习笔记------文件操作

编码 编码就是一种规则集合&#xff0c;记录了内容和二进制间进行相互转换的逻辑。 编码有许多中&#xff0c;我们最常用的是UTF-8编码 计算机只认识0和1&#xff0c;所以需要将内容翻译成0和1才能保存在计算机中。同时也需要编码&#xff0c;将计算机保存的0和1&#xff0c…

2.4 如何运行Python程序

如何运行Python程序&#xff1f; Python是一种解释型的脚本编程语言&#xff0c;这样的编程语言一般支持两种代码运行方式&#xff1a; 1) 交互式编程 在命令行窗口中直接输入代码&#xff0c;按下回车键就可以运行代码&#xff0c;并立即看到输出结果&#xff1b;执行完一行…

ReentrantLock加锁分析

1、ReentrantLock中其实是有一个AQS的子类实例的成员变量sync&#xff1b; 2、实际是调用的Sync中的lock&#xff1b;Sync是AQS的子类&#xff1b;Sync有两个子类&#xff0c;公平与非公平&#xff1b;默认为非公平&#xff1b;如下是非公平加锁分析&#xff1b; public Reentr…

Visual Basic6.0零基础教学(4)—编码基础,数据类型与变量

编码基础,数据类型与变量 文章目录 编码基础,数据类型与变量前言一、VB中的编程基础二、VB的基本字符集和词汇集1、字符集2、词汇集 VB中的数据类型VB中的变量与常量一.变量和常量的命名规则二.变量声明1.用Dim语句显式声明变量三. 常量 运算符和表达式一. 运算符 1. 算术运算符…

获取Book里所有sheet的名字,且带上超链接

应用背景&#xff1a; 当一个excel有很多sheet的时候&#xff0c;来回切换sheet会比较复杂&#xff0c;所以我希望excel的第一页有目录&#xff0c;可以随着sheet的增加&#xff0c;减少&#xff0c;改名而随时可以去更新&#xff0c;还希望有超链接可以直接跳到该sheet。 可以…

06-验证浮点数输入

鉴于shell脚本的限制和本事&#xff0c;浮点数&#xff08;或“实数”&#xff09;的验证过程乍一看似乎让人望而生畏&#xff0c;不过考虑到浮点数只不过是由小数点分隔的两个整数&#xff0c;再配合能够在脚本中引用其他脚本的能力&#xff08;validint&#xff09;&#xff…

13、Spring CLI中的特殊命令

特殊命令(Special Commands) 特殊命令是一个名为 . 的命令组的一部分。 操作系统 Shell 命令(OS Shell command) .! 命令在你启动 shell 的目录中运行一个操作系统命令。这个命令只在交互模式下工作。 如果在运行命令时遇到困难,你可能想尝试用双引号将其包围。然而,…

【爬取网易财经文章】

引言 在信息爆炸的时代&#xff0c;获取实时的财经资讯对于投资者和金融从业者来说至关重要。然而&#xff0c;手动浏览网页收集财经文章耗时费力&#xff0c;为了解决这一问题&#xff0c;本文将介绍如何使用Python编写一个爬虫程序来自动爬取网易财经下关于财经的文章 1. 爬…

前端基础 Vue -组件化基础

1.全局组件 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><script src&…

分布式任务队列:cppq

文章目录 简介FeaturesQuickstartExampleWeb UI命令行 参考 简介 cppq 是一个简单、可靠、高效的 C17 分布式任务队列。 cppq 是一个 C 库&#xff0c;用于对任务进行排队并与工作线程异步处理它们。它由 Redis 支持&#xff0c;旨在可扩展且易于入门。 cppq 工作原理&#x…

【QA】MySQL导出某数据库的所有数据为sql文件,包含建库命令、建表命令。

文章目录 前言Windows系统下 | mysqldump导出数据库数据Docker中导入初始化数据【补充】通过命令行&#xff0c;执行sql文件&#xff0c;将数据导入到数据库在MySQL外面执行在MySQL中执行 前言 我们在用docker部署mysql项目的时候&#xff0c;往往需要对数据库进行数据初始化。…

ARM 和 龙芯上 Arch Linux 安装手记

背景 今天尝试安装龙芯版 Linux,本来希望能安装 Debian 版,但只找到一些文档,没找到可安装版的 ISO。 后来顺着这篇文章找到了Arch Linux,就尝试安装了一下。 安装后发现竟然不会配置网络 😂。而且龙芯版由于是在 QEMU 虚拟机里,运行速度也较慢。所以,我想我需要先学…

Java-SSM电影在线播放系统

Java-SSM电影在线播放系统 1.服务承诺&#xff1a; 包安装运行&#xff0c;如有需要欢迎联系&#xff08;VX:yuanchengruanjian&#xff09;。 2.项目所用框架: 前端:JSP、layui等 后端:SSM,即Spring、SpringMvc、Mybatis等。 3.项目功能点: 3-1.后端功能: - 所有后台管理展…

rk3588内核添加特殊分辨率

rk平台内核本身默认支持一些常规的分辨率,如1920x1080@30,1280x720@60,但是往往不能满足需求,如有的客户需要你添加1020x700@35的分辨率,这时候就要自己加上去了。 下图是LCD各个参数对应的位置: 显示mode 各个参数含义如下: hdisplay:有效显示区水平像素数量,对应A…

Redis入门到实战-第十弹

Redis实战热身Geospatial篇 完整命令参考官网 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://redis.io/Redis概述 Redis是一个开源的&#xff08;采用BSD许可证&#xff09;&#xff0c;用作数据库、缓存、消息代…

Nginx配置文件中Location指令的匹配优先级

在 Nginx 中&#xff0c;当请求到达服务器时&#xff0c;会根据配置文件中的 location 指令来确定如何处理这个请求。location 指令有不同的匹配优先级&#xff0c;如下文所述。 location匹配优先级 精确匹配&#xff08;location /path&#xff09;&#xff1a;精确匹配优先…

C#手动改变自制窗体的大小

目录 1.Cursor类的Position属性 2.改变窗体大小的计算方法 3.Resources设计 &#xff08;1&#xff09;Resources资源图片管理 &#xff08;2&#xff09;GetObject方法设计 4.示例 当用户去除Winform窗体边框&#xff0c;自行设置窗体外观时&#xff0c;用户就不能使用W…

[综述笔记]Flexible large-scale fMRI analysis: A survey

论文网址&#xff1a;Flexible large-scale fMRI analysis: A survey | IEEE Conference Publication | IEEE Xplore 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff0…

关于网格数据导出指定格式的测试(以Gmsh导出nas格式为例)

本文主要讲述Gmsh如何导出nas格式的网格数据&#xff0c;众所周知&#xff0c;Gmsh可以导出多种网格数据格式&#xff0c;比如大家熟悉的msh、stl、inp、cgns&#xff08;似乎不完善&#xff09;等等&#xff0c;但是gmsh不支持nas格式的导出&#xff0c;只支持nas格式的导入&a…

银行量子金融系统应用架构设计

量子金融&#xff08;即Financial-Quantum&#xff0c;简称Fin-Q&#xff09;&#xff0c;特指量子科技在金融行业中的应用。 目前&#xff0c;量子科技中以量子保密通信、量子随机数和量子计算发展进度较快&#xff0c;取得了诸多阶段性重大技术突破和商用成果&#xff0c;这…