python内置装饰器

news2024/9/24 19:17:50

python内置装饰器

内置装饰器

  • 不用实例化、直接调用
  • 提升代码的可读性
    内置装饰器:classmethod类方法、staticmethod静态方法

普通方法

  • 定义:第一个参数为self,代表 实例本身
  • 调用:要有实例化的过程,通过 实例对象.方法名 调用
'''普通方法'''
#1. 定义
class MethodsDemo:
    param_a = 0 #类变量
    def normal_demo(self): # 定义一个类方法,第一个参数必须为self
      print("这是一个普通方法", self.param_a)

#2. 调用
md = MethodsDemo()
md.normal_demo()

输出结果为:这是一个普通方法 0

类方法

  • 定义:
  • 使用 @classmethod 装饰器,第一个参数为类本身,所以通常使用cls命名做区分(非强制)
    - 在类内可以直接使用类方法或类变量,无法直接使用实例变量或方法
  • 调用:无需实例化,直接通过 类.方法名 调用,也可以通过 实例.方法名 调用
''类方法'''
#1. 类的定义
class MethodsDemo:
    param_a = 0
    # 定义类方法必须加 classmethod装饰器
    @classmethod
    def classmethod_demo(cls):
        """
        类方法,第一个参数需要改为cls
        :return:
        """
        print("类方法", cls.param_a)
#2. 类的调用
MethodsDemo.classmethod_demo() #无需实例化,直接调用

输出结果为:类方法 0
调用普通方法一定要实例化

class MethodsDemo:
    CLASS_PARAM = 0

    def demo_method(self):  #实例方法
        print("这是一个普通方法")

    @classmethod
    def class_method(cls):
        print("这是一个类方法",cls.CLASS_PARAM)

#调用
MethodsDemo.class_method() #类方法可以直接调用
MethodsDemo.demo_method() #报错,实例化方法不可直接调用,需要实例化

输出结果为:
这是一个类方法 0
TypeError: MethodsDemo.demo_method() missing 1 required positional argument: ‘self’
实例化方法内,可以直接调用实例化方法
类方法内,不可以直接调用实例方法、实例变量;可以直接调用类方法、实例变量

class MethodsDemo:
    CLASS_PARAM = 0
    def __init__(self):  #初始化方法
        self.a = 'abc'
    def demo_method(self):  #实例方法
        print("这是一个普通方法")
    def demo_method2(self):
        self.demo_method() #实例化方法内,可以直接调用实例化方法
        print("这是一个普通方法2")
    @classmethod
    def class_method(cls):
        #cls.demo_method() #类方法内,不可以直接调用实例方法,TypeError: MethodsDemo.demo_method() missing 1 required positional argument: 'self'
        #cls.a  #类方法内,不可以直接调用实例变量,AttributeError: type object 'MethodsDemo' has no attribute 'a'
        print("这是一个类方法",cls.CLASS_PARAM)

    @classmethod
    def class_method2(cls):
        cls.class_method() #类方法内,可以直接调用类方法,实例变量
        print("这是一个类方法2",cls.CLASS_PARAM)

#调用
a1 = MethodsDemo()
a1.demo_method2()
#MethodsDemo.class_method()
MethodsDemo.class_method2()

输出结果为:
这是一个普通方法
这是一个普通方法2
这是一个类方法 0
这是一个类方法2 0

静态方法

  • 定义:
  • 使用 @staticmethod 装饰器,没有和类本身有关的参数
  • 无法直接使用任何类变量、类方法或者实例方法、实例变量
  • 调用:无需实例化,直接通过 类.方法名 调用,也可以通过 实例.方法名 调用
class MethodsDemo:
    param_a = 0
    @staticmethod #静态方法定义:1、要使用staticmethod装饰器 2、这个方法是没有self、或者cls
    def static_demo():
        print("静态方法") #无法直接调用类变量
#调用
MethodsDemo.static_demo()
a = MethodsDemo()
a.static_demo()

输出结果为:
静态方法
静态方法

普通方法、类方法、静态方法

在这里插入图片描述

实际案例

  • 右边的代码实现的需求是格式化输出时间
  • 如果现在需求变更,输入 年、月、日 没法保证格式统一,可能是json,可能是其他格式的字符串,在不修改构造函数的前提下,如何更改代码
class DateFormat:
    def __init__(self, year=0, month=0, day=0):
        self.year = year
        self.month = month
        self.day = day
    def out_date(self):
        return f"输入的时间为{self.year}年,{self.month}月,{self.day}日"

def json_format(json_data):
    year,month,day=json_data['year'],json_data['month'],json_data['day']
    # print(year,month,day)
    return year,month,day
print(json_format({"year":2021,"month":12,"day":24}))

year, month, day = json_format({"year":2021,"month":12,"day":24})
demo = DateFormat(year, month, day)
print(demo.out_date())

输出结果为:
(2021, 12, 24)
输入的时间为2021年,12月,24日

class DateFormat:
    def __init__(self, year=0, month=0, day=0):
        self.year = year
        self.month = month
        self.day = day
    def out_date(self):
        return f"输入的时间为{self.year}年,{self.month}月,{self.day}日"

    @classmethod
    def json_format(cls,json_data):
        '''输入一个字典格式的数据信息,返回(2021, 12, 24)'''
        year, month, day = json_data['year'], json_data['month'], json_data['day']
        return cls(year,month,day)
json_data ={"year":2021,"month":12,"day":24}
#使用json格式化,生成想要的日期格式,返回DateFormat实例
demo = DateFormat.json_format(json_data)
print(demo.out_date())

输出结果为:
输入的时间为2021年,12月,24日

静态方法实际案例

此方法没有任何和实例、类相关的部分,可以作为一个独立函数使用
某些场景下,从业务逻辑来说又属于类的一部分
例子:比赛

'''多轮比赛,每轮由两个不同的英雄对打'''
class Game:
    def __init__(self,first_hero,second_hero):
        self.first_hero = first_hero
        self.second_hero = second_hero
    #fight 有和实例变量交互的部分,所以需要定义为一个普通方法
    def fight(self):
        print(f"本来比赛开始,由{self.first_hero} VS {self.second_hero}")
    #start 没有和类和实例交互的部分,那么就可以使用staticmethod
    @staticmethod
    def start():
        print("游戏开始")

Game.start()
game1 =Game("11","22")
game2 =Game("一一","二二")
game1.fight()
game2.fight()

输出结果为:
游戏开始
本来比赛开始,由11 VS 22
本来比赛开始,由一一 VS 二二

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

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

相关文章

JavaSE——数据类型与变量

1. 数据类型 在 Java 中数据类型主要分为两类: 基本数据类型 和 引用数据类型 。 基本数据类型有 四类八种 : 1. 四类:整型、浮点型、字符型以及布尔型 2. 八种: 数据类型关键字内存占用范围字节型byte1 个字节-128~127短整型…

「渗透笔记」致远OA A8 status.jsp 信息泄露POC批量验证

前言部分 在本节中,我会分两部分来说明致远OA A8 status.jsp 信息泄露的验证问题,其实就是两种验证方式吧,都一样,都是批量验证,主要如下所示: 通过Python脚本进行批量验证,但是前提是你可以收…

rider下ef core迁移

新建数据库 create database mockstu新建web项目 安装Microsoft.EntityFrameworkCore.SqlServer包 设置连接字符串 新建model using MockStuWeb.Models.EnumTypes; using System.ComponentModel.DataAnnotations;namespace MockStuWeb.Models {/// <summary>/// 学生…

Redis实战篇-1

实战篇Redis 开篇导读 短信登录 这一块我们会使用redis共享session来实现 商户查询缓存 通过本章节&#xff0c;我们会理解缓存击穿&#xff0c;缓存穿透&#xff0c;缓存雪崩等问题&#xff0c;让小伙伴的对于这些概念的理解不仅仅是停留在概念上&#xff0c;更是能在代码…

vs2019新建Qt工程中双击 .ui 文件无法打开

vs2019 中创建的 Qt 工程&#xff0c;在使用的过程中&#xff0c;经常会有&#xff1a;双击 .ui 文件&#xff0c;闪退的情况&#xff0c;也即 .ui 文件无法打开&#xff01; 针对该问题的详细解决步骤如下&#xff1a; 1、右击该 .ui 文件&#xff0c;选择“打开方式” 2、…

思通舆情 是一款开源免费的舆情系统 介绍

思通舆情 是一款开源免费的舆情系统。 支持本地化部署&#xff0c;支持在线体验。 支持对海量舆情数据分析和挖掘。 无论你是使用者还是共同完善的开发者&#xff0c;欢迎 pull request 或者 留言对我们提出建议。 您的支持和参与就是我们坚持开源的动力&#xff01;请 sta…

【数据结构基础】之八大排序(C语言实现)

【数据结构基础】之八大排序(C语言实现&#xff09; &#x1f427; 冒泡排序♈️ 冒泡排序原理及代码实现♈️ 稳定性分析 &#x1f427; 选择排序♈️ 选择排序原理及代码实现♈️ 稳定性分析 &#x1f427; 插入排序♈️ 插入排序的原理及代码实现♈️ 稳定性分析 &#x1f4…

【数据结构】猛猛干7道链表OJ

前言知识点 链表的调试技巧 int main() {struct ListNode* n1(struct ListNode*)malloc(sizeof(struct ListNode));assert(n1);struct ListNode* n2(struct ListNode*)malloc(sizeof(struct ListNode));assert(n2);struct ListNode* n3(struct ListNode*)malloc(sizeof(struc…

GAMMA数据处理问题(七)

phase_sim_orb报这个错是什么原因呢&#xff0c;说是我的hgt文件和模拟的干涉图行数不匹配&#xff0c;之前geocode生成hgt的参数不是在mli.par文件中看吗&#xff0c;为什么会出现行数不匹配的情况啊&#xff0c;难道不是par文件中里面看&#xff1f;&#xff1f;&#xff1f;…

力扣hot100:153. 寻找旋转排序数组中的最小值(二分的理解)

由力扣hot100&#xff1a;33. 搜索旋转排序数组&#xff08;二分的理解&#xff09;-CSDN博客&#xff0c;我们知道二分实际上就是找到一个策略将区间“均分”。对于旋转数组问题&#xff0c;在任何位置分开两个区间&#xff0c;如果原区间不是顺序的&#xff0c;分开后必然有一…

[ROS 系列学习教程] rqt可视化工具箱 - Topic工具

ROS 系列学习教程(总目录) 本文目录 一、Message Publisher二、Message Type Browser三、Topic Monitor 一、Message Publisher Message Publisher 可以通过可视化界面发布topic。 启动方法&#xff1a; 在 rqt 窗口依次点击 Plugins -> Topics -> Message Publisher 启…

抖音平台热销的本腾和新讯随身WiFi,哪个更靠谱,更值得购买?

经常有粉丝朋友摆脱小编测评一下在某短视频平台上面非常火爆的两款随身WiFi&#xff0c;本腾随身WiFi和新讯随身WiFi到底哪个更好。今天&#xff0c;小编就为大家带来最真实的体验测评。 一、外观和产品 这方面新讯要比本腾做的更好&#xff0c;本腾的设备相对单一一些。新讯则…

关于Java发邮件提醒写周报实现(二)代码编写

背景 由于公司每周都要写周报&#xff0c;而日常工作很忙&#xff0c;所以很容易忘记这件事件&#xff0c;因此开发一个写周报提醒的机器人&#xff0c;进行特定时间提醒是时候写周报了。 有一个大前提&#xff0c;本技术实现&#xff0c;本着不开通任何收费服务的态度去考察使…

入门linux之Ubuntu学习

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1、介绍Ubuntu2、虚拟机目录解析3、常用指令ls&#xff1a;罗列当前目录文件信息对ls -l 的结果解析1.第一个字符2.每三个字符&#xff08;第一个字符后&#x…

服务器软件express搭建web服务器

文章目录 1.express 是什么2.路由2.1&#xff08;参数一&#xff09;读取用户的请求&#xff08;request&#xff09;2.2&#xff08;参数二&#xff09;给用户响应&#xff08;response&#xff09;2.3&#xff08;参数三&#xff09;next()函数&#xff08;传递请求到下一个处…

卡尔曼滤波跟踪自由落体的高度程序,带MATLAB例程

背景 已知一物体做自由落体运动,对其高度进行20次测量,测量值如下表:(g=9.80m/s2). 设高度的测量误差分布为: N(0, 1),该物体的初始高度h0和速度v0分布也为高斯分布,且: 试求该物体高度和速度的随时间变化的最优估计(matlab Kalman filters)。N(0, 1),该物体的初始高…

【QT入门】 Qt实现自定义信号

往期回顾&#xff1a; 【QT入门】图片查看软件(优化)-CSDN博客 【QT入门】 lambda表达式(函数)详解-CSDN博客 【QT入门】 Qt槽函数五种常用写法介绍-CSDN博客 【QT入门】 Qt实现自定义信号 一、为什么需要自定义信号 比如说现在一个小需求&#xff0c;我们想要实现跨ui通信&a…

计算机实体安全

计算机实体安全定义&#xff1a; 对场地环境、设施、设备和载体、人员采取的安全对策和措施。 一、计算机可靠性与故障分析 1.1 计算机的可靠性 可靠性 (狭义) ■计算机在规定时间与条件下完成规定功能的 概率 ■规定条件&#xff1a;环境条件&#xff0c;使用条件&#xff0…

计数质数——算法思路

题目链接&#xff1a;204. 计数质数 - 力扣&#xff08;LeetCode&#xff09; 会超时的代码&#xff1a; 使用了枚举的方法 方法一&#xff1a; public static int countPrimes(int n) {int ans1;if (n<2)return 0;for (int i3;i<n;i){boolean flagtrue;for (int j2;j&…

docker安装WireGuard服务

启动 WireGuard 如下异常 则是linux内核需要升级 $ wg-quick down wg0 $ wg-quick up wg0 Error: WireGuard exited with the error: Cannot find device "wg0" This usually means that your hosts kernel does not support WireGuard!at /app/lib/WireGuard.js:65…