Chapter 26 Python魔术方法

news2024/9/30 0:28:26

欢迎大家订阅【Python从入门到精通】专栏,一起探索Python的无限可能!

文章目录

  • 前言
  • 一、什么是魔术方法?
  • 二、常见的魔术方法
    • ① __init__构造方法
    • ② __str__字符串方法
    • ③ __lt__比较方法
    • ④ __le__比较方法
    • ⑤ __eq__比较方法


前言

本章将详细讲解 Python 的魔术方法,包括其定义以及一些常见的具体实现。


本篇文章参考:黑马程序员

一、什么是魔术方法?

①定义
在Python中,魔术方法(也称为特殊方法或双下方法)是以双下划线开始和结束的方法。这些方法提供了对Python内置操作的自定义实现,从而允许用户控制对象的行为。魔术方法通常不直接调用,而是由Python在特定操作中自动调用。

②作用

  • 简化代码
  • 增强对象行为
  • 提供方便的接口
  • 增强可读性和可维护性
  • 实现对象之间的灵活交互

魔术方法是 Python 中强大而灵活的功能,使得自定义类能够与语言中的基本特性和运算符无缝集成。它们不仅提升了代码的可读性和可维护性,还遵循了面向对象编程的原则,为开发人员提供了更多的设计自由。

二、常见的魔术方法

常见的魔术方法:
在这里插入图片描述

① __init__构造方法

class Student:
    name=None          # 记录学生姓名
    gender=None        # 记录学生性别
    age=None           # 记录学生年龄

stu_1=Student()
stu_1.name="小明"
stu_1.gender="男"
stu_1.age="15"

stu_2=Student()
stu_2.name="小红"
stu_2.gender="女"
stu_2.age="18"

在上面这段代码中,为对象的属性赋值需要依次进行,略显繁琐。

思考:那有没有更加高效的方式能够一行代码就完成呢?Student()这个括号能否像函数(方法)那样,通过传参的形式对属性赋值呢?
答:可以,需要使用__init__()方法。

定义:
在Python中,构造方法是一种特殊的方法,用于初始化对象的属性。构造方法的名称是 __init__()。它在创建对象时自动调用。通过构造方法,可以为新创建的对象设置初始状态或属性值。

作用:

  • 构建类对象的时候会自动运行
  • 构建类对象的传参会传递给构造方法,借此特性可以给成员变量赋值

注意事项:

  • 构造方法也是成员方法,不要忘记在参数列表中提供self关键字
  • 在构造方法内定义成员变量,需要使用self关键字
class Student:
    def __init__(self,name,age,tel):
        self.name=name
        self.age=age
        self.tel=tel
        print("Student类创建了一个类对象")

stu=Student("小明","18","13426272890")
print(stu.name)
print(stu.age)
print(stu.tel)

输出结果:
Student类创建了一个类对象
小明
18
13426272890

【分析】
在这里插入图片描述
self.name = name这行代码的作用是将参数 name 的值赋给对象的 name 属性,确保每个 Student 对象都有自己的 name。

  • self 是对象的实例,指向当前创建的对象
  • self.name 是对象的属性(实例变量),用于存储学生的名字
  • name 是构造方法的参数,即在创建对象时传入的值

② __str__字符串方法

__str__字符串方法可返回对象的字符串表示,通常用于使用print()函数时。

class Student:
    # 构造方法
    def __init__(self,name,age,tel):
        self.name=name
        self.age=age
        self.tel=tel

stu=Student("小明","18","13456789021")
print(stu)
print(str(stu))

输出结果:
<main.Student object at 0x000001C3F0FEA030>
<main.Student object at 0x000001C3F0FEA030>

当类的对象被转换为字符串时,通常输出的是内存地址,这样的表示并没有太大意义。为了提供更有用的信息,我们可以通过定义 __str__字符串方法来控制对象在转换为字符串时的行为。

class Student:
    # 构造方法
    def __init__(self,name,age,tel):
        self.name=name
        self.age=age
        self.tel=tel

    # __str__魔术方法
    def __str__(self):
        return f"Student类对象,姓名:{self.name},年龄:{self.age},电话:{self.tel}"


stu=Student("小明","18","13456789021")
print(stu)
print(str(stu))

输出结果:
Student类对象,姓名:小明,年龄:18,电话:13456789021
Student类对象,姓名:小明,年龄:18,电话:13456789021

③ __lt__比较方法

__lt__比较方法用于定义小于 (<) 运算符的行为,当你用 a < b 进行比较时,实际上会调用 a __lt__(b),返回一个布尔值 (True 或 False)。

class Student:
    # 构造方法
    def __init__(self,name,age,tel):
        self.name=name
        self.age=age
        self.tel=tel
        
stu1=Student("小明","18","13456789021")
stu2=Student("小红","17","13786789021")
print(stu1<stu2)

输出结果:
在这里插入图片描述
直接对两个对象进行比较是不可行的,但如果在类中实现 __lt__方法,就可以使用小于符号进行比较。同时,根据定义的逻辑,也可以实现大于符号的比较。

class Student:
    # 构造方法
    def __init__(self,name,age,tel):
        self.name=name
        self.age=age
        self.tel=tel
        
    # __lt__魔术方法
    def __lt__(self, other):
        return self.age<other.age

stu1=Student("小明","18","13456789021")
stu2=Student("小红","17","13786789021")
print(stu1<stu2)
print(stu1>stu2)

输出结果:
False
True

【分析】
在这里插入图片描述
return self.age < other.age 这行代码执行实际的比较。 self 表示调用该方法的对象实例; other 表示与 self 进行比较的另一个对象实例。如果 self 对象的 age 小于 other对象的 age,那么返回 True;否则返回 False。

④ __le__比较方法

__le__比较方法用于定义小于或等于 (<=) 运算符的行为,你用 a <= b 进行比较时,会调用 a __le__(b),返回一个布尔值 (True 或 False)。

class Student:
    # 构造方法
    def __init__(self,name,age,tel):
        self.name=name
        self.age=age
        self.tel=tel

    # __le__魔术方法
    def __le__(self, other):
        return self.age<=other.age

stu1=Student("小明","18","13456789021")
stu2=Student("小红","17","13786789021")
print(stu1<=stu2)
print(stu1>=stu2)

输出结果:
False
True

⑤ __eq__比较方法

__eq__比较方法用于定义相等 (==) 运算符的行为,当你用 a == b 进行比较时,会调用 a __eq__(b), 返回值为布尔值 (True 或 False)。

class Student:
    # 构造方法
    def __init__(self,name,age,tel):
        self.name=name
        self.age=age
        self.tel=tel

stu1=Student("小明","18","13456789021")
stu2=Student("小红","17","13786789021")
print(stu1==stu2)

输出结果:
False

在 Python 中,使用== 运算符比较对象时,默认情况下比较的是对象的内存地址,而不是其内容。所以== 运算符判断的是两个对象是否是同一个实例。因为 stu1 和 stu2 是两个不同的 Student 实例,它们在内存中占用不同的空间。因此,它们的内存地址不同,比较结果为 False。

实现 __eq__比较方法,我们可以根据对象的属性自定义相等性判断。

class Student:
    # 构造方法
    def __init__(self,name,age,tel):
        self.name=name
        self.age=age
        self.tel=tel

    # __eq__魔术方法
    def __eq__(self, other):
        return self.age <= other.age

stu1=Student("小明","18","13456789021")
stu2=Student("小红","17","13786789021")
stu3=Student("小齐","17","13786745521")
print(stu1==stu2)
print(stu2==stu3)

输出结果:
False
True

【例题】
开学了有一批学生信息需要录入系统,请设计一个类,记录学生的姓名、年龄、电话这3类信息。要求通过for循环,配合input输入语句,并使用构造方法,完成学生信息的键盘录入。输入完成后,使用print语句,完成信息的输出。

class Student:
    # 构造方法
    def __init__(self,name,age,tel):
        self.name=name
        self.age=age
        self.tel=tel

    # 魔法方法,用于定义对象的字符串表示形式
    def __str__(self):
        return f"【学生姓名:{self.name},学生年龄:{self.age},学生电话:{self.tel}】"

total_students=int(input("请输入需要录入的学生总数:"))
students=[]
# for循环,用于迭代一个由 range 生成的序列。
# range(total_students): range 函数生成一个从 0 到 total_students - 1 的整数序列
# 比如,如果 total_students 是 2,那么 range(2) 会生成 [0, 1]
for i in range(total_students):
    print(f"当前录入第{i+1}位学生信息,总共需录入{total_students}位学生信息")

    name=input("请输入学生姓名:")
    age=input("请输入学生年龄:")
    tel=input("请输入学生电话:")

    student=Student(name,age,tel)
    students.append(student)
    print(f"学生{i+1}信息录入完成,信息为{student}")

print("所有学生信息录入完成,信息如下:")
for student in students:
    print(student)

输出结果示例:
在这里插入图片描述

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

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

相关文章

RabbitMQ高级特性 - 消费者消息确认机制

文章目录 RabbitMQ 消息确认机制背景消费者消息确认机制概述手动确认&#xff08;RabbitMQ 原生 SDK&#xff09;手动确认&#xff08;Spring-AMQP 封装 RabbitMQ SDK&#xff09;AcknowledgeMode.NONEAcknowledgeMode.AUTO&#xff08;默认&#xff09;AcknowledgeMode.MANUAL…

思源笔记软件的优缺点分析

在过去一年里&#xff0c;我用了很多款笔记&#xff0c;从word文档到onenote到语雀再到思源&#xff0c;最后坚定的选择了思源笔记 使用感受 首先是用word文档来记笔记&#xff0c;主要是开始时不知道笔记软件怎么好用&#xff0c;等到笔记越来越膨胀的时候我发现&#xff0c…

2024死磕小红书,一定能赚到钱!

​2024死磕小红书&#xff0c;一定能赚到钱&#xff01;在文末领取小红书运营完全指南电子书 从2023年起&#xff0c;小红书这股热乎劲儿就像开了挂&#xff0c;突然间就成了人人想蹭的“显学”。大伙儿都想趁着平台红利期&#xff0c;分一杯羹。说来惭愧&#xff0c;我从2020年…

C语言指针·高级用法超详解(指针运算、野指针、悬空指针、void类型指针、二级以及多级指针)

目录 1. 指针的运算 2. 野指针和悬空指针 2.1 野指针 2.2 悬空指针 3. void类型指针 4. 二级指针和多级指针 4.1 命名规则 4.2 作用 4.2.1 二级指针可以操作一级指针记录的地址 4.2.2 利用二级指针获取变量中记录的数据 1. 指针的运算 文章开始前可以先了…

基于强化学习的Deep-Qlearning网络玩cartpole游戏

1、环境准备&#xff0c;gym的版本为0.26.2 2、编写网络代码 # 导入必要的库 import gym import torch import torch.nn as nn import torch.optim as optim import numpy as np from collections import deque import random# 定义DQN网络 class DQN(nn.Module):def __init__…

《深入浅出WPF》学习笔记五.Mvvm设计模式

《深入浅出WPF》学习笔记五.Mvvm设计模式 背景 在通过视频学习wpf的过程中&#xff0c;讲师花了不少篇幅来讲Mvvm。特地在此用自己的语言总结一番,方便以后面试回答&#xff0c;如有理解不对&#xff0c;欢迎指正哈。 Mvvm结构 Mvvm指的是ModelViewViewModel 为什么要使用…

《网络安全自学教程》- MySQL匿名用户的原理分析与实战研究

《网络安全自学教程》 低版本的MySQL数据库在安装时会创建一个用户名和密码为空的账户&#xff0c;也就是匿名账户。即使升级到高版本&#xff0c;匿名账户仍然会存在。 MySQL匿名账户 1、检查是否存在匿名账户2、检查用户权限3、创建匿名账户4、使用匿名账户登录5、删除匿名账…

医院管理系统

医院管理系统 本文所涉及所有资源均在传知代码平台可获取 文章目录 医院管理系统概述使用技术核心功能1. 登录与注册2. 管理员系统3. 患者系统&#xff08;医院电子平台&#xff09;4. 医生系统&#xff08;坐诊系统&#xff09; 部署与启动适用场景 概述 本项目是一个专为大学…

读零信任网络:在不可信网络中构建安全系统09用户信任

1. 用户信任 1.1. 将设备身份和用户身份混为一谈会导致一些显而易见的问题 1.1.1. 特别是当用户拥有多台设备时&#xff0c;而这种情况很普遍 1.1.2. 应该针对不同类型的设备提供相匹配的凭证 1.1.3. 在存在共用终端设备的情况下&#xff0c;所有的这些问题将更加凸显 1.2…

打造未来交互新篇章:基于AI大模型的实时交互式流媒体数字人项目

在当今数字化浪潮中,人工智能(AI)正以前所未有的速度重塑我们的交互体验。本文将深入探讨一项前沿技术——基于AI大模型的实时交互式流媒体数字人项目,该项目不仅集成了多种先进数字人模型,还融合了声音克隆、音视频同步对话、自然打断机制及全身视频拼接等前沿功能,为用…

Python中使用正则表达式

摘要&#xff1a; 正则表达式&#xff0c;又称为规则表达式&#xff0c;它不是某种编程语言所特有的&#xff0c;而是计算机科学的一个概念&#xff0c;通常被用来检索和替换某些规则的文本。 一.正则表达式的语法 ①行定位符 行定位符就是用来描述字符串的边界。"^&qu…

第十三节、人物属性及伤害计算

一、碰撞器层级剔除 选中player和敌人&#xff0c;即可去除 若勾选触发器&#xff0c;则会取消掉碰撞效果&#xff0c;物体掉落 二、人数属性受伤计算 1、创建代码 将两个代码挂载到玩家和敌人身上 2、调用碰撞物体的方法 3、伤害值 开始&#xff1a;最大血量即为当前血量…

Arduino PID库 (6):初始化

Arduino PID库 &#xff08;6&#xff09;&#xff1a;初始化 参考&#xff1a;手把手教你看懂并理解Arduino PID控制库——初始化 Arduino PID库 &#xff08;5&#xff09;&#xff1a;开启或关闭 PID 控制的影响 问题 在上一节中&#xff0c;我们实现了关闭和打开PID的功…

最小二乘法求解线性回归问题

本文章记录通过矩阵最小二乘法&#xff0c;求解二元方程组的线性回归。 假设&#xff0c;二维平面中有三个坐标&#xff08;1&#xff0c;1&#xff09;、&#xff08;2&#xff0c;2&#xff09;、&#xff08;3&#xff0c;2&#xff09;&#xff0c;很显然该三个坐标点不是…

React(三):PDF文件在线预览(简易版)

效果 依赖下载 https://mozilla.github.io/pdf.js/getting_started/ 引入依赖 源码 注意&#xff1a;pdf文件的预览地址需要配置代理后才能显示出来 import ./index.scss;function PreviewPDF() {const PDF_VIEWER_URL new URL(./libs/pdfjs-4.5.136-dist/web/viewer.html, im…

12.SpringDataRedis

介绍 SpringData是Spring中数据操作的模块&#xff0c;包含对各种数据库的集成&#xff0c;其中redis的集成模块就叫做SpringDataRedis。 spring的思想从来都不是重新生产&#xff0c;而是整合其他技术。 SpringDataRedis的特点 1.提供了对不同redis客户端的整合&#xff08…

8.4 day bug

bug1 忘记给css变量加var 复制代码到通义千问&#xff0c;解决 bug2 这不是我的bug&#xff0c;是freecodecamp的bug 题目中“ 将 --building-color2 变量的颜色更改为 #000” “ 应改为” 将 #000 变量的颜色更改为 --building-color2 “ bug3 又忘记加var(–xxx) 还去问…

渗透小游戏,各个关卡的渗透实例

Less-1 首先&#xff0c;可以看见该界面&#xff0c;该关卡主要是SQL注入&#xff0c;由于对用户的输入没有做过滤&#xff0c;使查询语句进入到了数据库中&#xff0c;查询到了本不应该查询到的数据 首先&#xff0c;如果想要进入内部&#xff0c;就要绕过&#xff0c;首先是用…

C#中的TCP和UDP

TcpClient TCP客户端 UDP客户端 tcp和udp的区别 TCP&#xff08;传输控制协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;是两种在网络通信中常用的传输层协议&#xff0c;它们在C#或任何其他编程语言中都具有相似的特性。下面是TCP和UDP的主要区别&#xff1a;…

MySQL的基本使用

文章目录 MySQL的基本使用什么是SQLSQL学习目标SQL的SELECT语句SQL的INSERT INTO语句 SQL的UPDATE语句SQL的DELETE语句 SQL的WHERE子句可在WHERE子句中使用的运算符SQL的AND和OR运算符SQL的ORDER BY子句SQL的COUNT(*)函数 在项目中操作数据库的步骤安装mysql模块配置mysql模块测…