Python中__面向对象__学习 (上)

目录

一、类和对象

1.类的定义

2.根据对象创建类

二、构造和析构

1.构造方法

(1)不带参数的构造方法

(2)带参数的构造方法

2.析构方法

三、重载

1.定制对象的字符串形式

(1)只重载__str__方法

(2)只重载__repr__方法

(3)重载__str__和__repr__方法

2.运算符重载

(1)加法运算重载

(2)索引和分段重载

一、类和对象

1.类的定义

类是创建对象的基础模板。它为对象提供了创建的要求。类由以下三部分组成:

(1)类名: 类的名称,它的首字母必须是大写,如:Cat

(2)属性: 定义属性(变量)用于描述事物的特征,比如:人的姓名、年龄等特征是类中定义的数据。

(3)方法: 方法(函数)用于描述事物的行为,比如,人会说话、微笑等类的行为。

示例:

上述例子中,我们定义了一个Cat的类,类的对象的参数固定第一个self,self代表类的对象自己,后面可引用对象的属性和方法,self 可以有‘类属性’和‘实例属性’。

所谓类属性,即:由类的所有实例共享。它们在类定义的顶部声明,不需要使用 self 参数。

所谓实例属性,即:属于类的每个特定实例,每个实例都有独自的属性内容。它们在类的初始化方法 __init__ 中 通过使用 self 参数来声明。

例子中的move、jump、index都是实例属性。

类属性示范:

class Cat:
    black = "black cat detective"  # 这里black是类属性

2.根据对象创建类

格式如下:

对象名 = 类名(自定义参数)

# 创建一个对象,并对该变量对象保持引用
tom = Cat(2,1)

紧接着给对象加属性的格式:

对象名 . 新的属性值  =  值

# 添加 颜色 属性
tom.color = '橘色'

完整栗子:

class Cat:  # 定义一个Cat父类
    def __init__(self, move, scratch):
        self.move = move  # 给Cat类增加move属性的构造方法
        self.scratch = scratch  # 将参数scratch赋值给scratch属性

        # 实例属性 index
        self.index = {'weight': f'{0.5}kg', 'height': f'{5} cm'}

# 创建一个对象,并对该变量对象保持引用
tom = Cat(2, 1)

# 给创建好的对象增加额外的属性
tom.color = '橘色'

# 访问属性
print("一只" + tom.color + "的猫干的好事!")
print("打碎杯子:", tom.move)
print("抓坏枕头:", tom.scratch)
print(tom.index)

二、构造和析构

1.构造方法

如果每创建一个类的对象,建一个对象,还想就添加一次属性,这样显然非常麻烦。

为此Python 提供了一个构造方法来解决这个问题,可以在创建对象的时候就设置多个属性。该方法就是上面用到的 __init__ (两个下划线开头、两个下划线结尾),当创建类的实例属性时,系统会自动调用构造方法,从而实现对类进行初始化的操作。

(1)不带参数的构造方法

即:就单独一个(self)。示范:

class Car:
    # 不带参数的构造方法
    def __init__(self):
        self.color = '黑色'

    def wait(self):
        print(f"一辆{self.color}的车在等候...")

car = Car()
car.wait()
(2)带参数的构造方法

有时属性值一样,不利于构造的扩展。所以通过传入参数来修改属性的值就很方便。

示范:

class Car:
    # 带参数构造方法
    def __init__(self, color):
        self.color = color

    # 鸣笛
    def toot(self):
        print(f"{self.color}色的车在鸣笛...")

    # 等候
    def wait(self):
        print(f"{self.color}色的车在等候...")

# 对象1
BMW = Car("白")
# 对象2
TOYOTA = Car("灰")
# 开始调用
BMW.toot()
TOYOTA.wait()

2.析构方法

当一个对象的运行周期结束时,Python 解释器会通过调用__del__()的方法删除调用的对象,来释放内存资源,这样的方法称为‘析构’。

继续上面的例子(带有析构):

class Car:
    # 带参数构造方法
    def __init__(self, color):
        self.color = color

    # 鸣笛
    def toot(self):
        print(f"{self.color}色的车在鸣笛...")

    # 等候
    def wait(self):
        print(f"{self.color}色的车在等候...")

    '''根据python自动回收垃圾机制会自动
    删除周期结束的对象并释放内存空间'''
    def __del__(self):
        print("-------")

# 对象1
BMW = Car("白")
# 对象2
TOYOTA = Car("灰")
# 开始调用
BMW.toot()
TOYOTA.wait()

del BMW  # 手动删除调用的对象1,释放内存空间
print("BMW对象已被删除")
del TOYOTA  # 手动删除调用的对象2,释放内存空间
print("TOYOTA对象已被删除")

总之,处理多个对象或者有循环调用对象时,析构是个方法。并且Python会在对象生命周期结束时自动进行垃圾回收,所以有时我们可以不需要显式的定义__del__方法。

三、重载

重载通常指的是能够定义多个同名函数,但是它们的参数列表(类型或数量)不同。Python本身不支持函数重载的语法,因为它是动态类型的语言,参数的类型在运行时确定。不过,可以通过默认参数值、可变参数(不定长参数)或使用装饰器等方式来模拟类似重载的行为。

与“重载”相比,重写发生在继承体系中,子类中的方法与父类中同名方法具有相同的参数列表和返回类型。子类通过重写方法来提供特定的实现,覆盖父类的行为。

1.定制对象的字符串形式

(1)__str__实例方法

使用__str__方法,即:能让print打印出调用的参数结果,例:

class Vehicle:

    def __init__(self, price, fuel_consumption):
        # 给初始化的参数赋值给实例的属性
        self.price = price
        self.fuel_consumption = fuel_consumption

    # 重载方法
    def __str__(self):  # 将对象转换为字符串时能被自动调用
        return f"售价:{self.price}  油耗:{self.fuel_consumption}"

su7 = Vehicle("22万", 0)  # 创建一个Vehicle的实例,传递22万、0 参数

print(su7)

// ^-^ 

如果没有写__str__实例方法:

 就只会显示对象所在的地址(这并不是我们所想要的结果)

(2)__repr__实例方法

重载 __repr__ 方法,可以保证各种操作下都能正确获得实例对象自定义的字符串形式。与__str__方法相比, __repr__ 用于获取对象的字符串表示时,通常用于开发者调试。当使用__repr__ ()函数或在交互式解释器中打印对象时,__repr__方法被调用。__repr__应该返回一个字符串,且该字符串应该是一个有效的Python表达式,能够重新创建该对象。

示例:

(3)__str__和__repr__实例方法

总之,__str__和__repr__ 都能对自定义对象返回有效的字符串形式。

2.运算符重载

Python 中的运算符重载是一种特殊的多态性形式,运算符重载让我们能够对自定义的对象使用熟悉的运算符,如加法(+)、减法(-)、乘法(*)等。

就比如以下代码,我们给加号赋予一个作用:

class Shop:

    def __init__(self, price, bonus_point):
        self.price = price
        self.bonus_point = bonus_point

    # 通过两个对象的相加,返回到类中
    def __add__(self, other):
        return Shop(self.price + other.price,
                    self.bonus_point + other.bonus_point)

    def __str__(self):  # 确保能返回我们自定义的字符串
        return f"消费金额:{self.price},奖励积分:{self.bonus_point}"

    def __repr__(self):  # 保证各种操作下都能让自定义对象有字符串形式
        return f"消费金额:{self.price},奖励积分:{self.bonus_point}"

nanfu_battery = Shop(9, 0.5)
air_conditioning = Shop(6999, 100)

# 这里就是通过自定义对象的相加给‘+’运算符 赋予的功能
total = nanfu_battery + air_conditioning

print(total)

在 Python 中,运算符重载通过在类中定义特殊方法来实现。这些特殊方法以双下划线开始和结束,例如__add__、__sub__、__mul__等,常见的如下:

(1)加法运算重载

当两个实例对象进行加法时,自动调用__add__方法,例:

class Vector:  # 定义一个 Vector(向量)的类
    # 构建函数,通过[:]切片复制一个新对象,而不影响原来的对象
    def __init__(self, other):
        self.data = other[:]

    # 加法重载
    def __add__(self, other):
        # 计算 self.data 和 other.data 的长度的最小值
        min_len = min(len(self.data), len(other.data))
        # 创建一个变量,用于存放结果
        result_list = []

        # 遍历两个列表的最小长度
        for i in range(min_len):
            result_list.append(self.data[i] + other.data[i])

        # 判断哪个列表更长,并添加剩余的元素
        if len(self.data) > min_len:
            result_list.extend(self.data[min_len])
        elif len(other.data) > min_len:
            result_list.extend(other.data[min_len])

        # 返回包含相加的结果
        return Vector(result_list)

# 创建Vector(向量)类的两个实例
one = Vector([4, 5])
two = Vector([6, 7])

demo_sum = one + two

print("相加结果:", demo_sum.data)

其实、在单纯的调用运算符重载的计算中,主要是要考虑好计算的边界问题就行吧.......(好难啊!)

(2)索引和分段重载

索引和分片相关的重载方法主要包括以下三个:

示例:

class MyList:
    # 先构造一个初始化函数
    def __init__(self, initial_data):
        self.data = initial_data

    # 定义索引、分片的重载
    def __getitem__(self, key):
        return self.data[key]

    # 定义索引、分片赋值的重载
    def __setitem__(self, key, value):
        self.data[key] = value

    # 删除索引、分片的重载
    def __delitem__(self, key):
        del self.data[key]

    # 使用repr函数用来返回self.data字符串形式
    def __repr__(self):
        return repr(self.data)

# 创建一个实例
list = MyList([1, 2, 3, 4, 5])

print(list[1])  # 索引出位置1的值
print(list[:])  # 分片返回列表全部的值
print(list[1:3])  # 分片位置1-3(不含)的值

print("-"*20)  # 一条分割线...

list[1] = 10  # 将索引1的元素改为10
list[2:4] = [8, 9]  # 将索引2到3的元素替换为[8, 9]

print(list)  # 输出新的列表

print("-"*20)  # 一条分割线...

del list[1]  # 删除索引1的元素
del list[1:3]  # 删除索引1到2的元素

print(list)  # 再输出新的列表

P.S.

端午假期愉快!\(*^▽^*)/

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

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

相关文章

STM32 HAL库开发——入门篇(3):OLED、LCD

源自正点原子视频教程: 【正点原子】手把手教你学STM32 HAL库开发全集【真人出镜】STM32入门教学视频教程 单片机 嵌入式_哔哩哔哩_bilibili 一、OLED 二、内存保护(MPU)实验 2.1 内存保护单元 三、LCD 3.1 显示屏分类 3.2 LCD简介 3.3 LCD…

【JAVASE】日期与时间类(上)

一:概述 从JAVA SE 8开始提供了java.time包,该包中有专门处理日期和时间的类。 LocalDate LocalDateTime 和LocalTime 类的对象封装和日期、时间有关的数据,这三个类都是final类,而且不提供修改数据的方法,即这…

ai辅助教育孩子

孩子经常躺在床上看手机是一个需要关注的问题,因为这不仅可能影响他们的视力健康,还可能影响睡眠质量和身体健康。以下是一些建议,帮助应对这一问题: 设定明确的规定: 与孩子一起制定使用手机的规则,如每天…

前端多人项目开发中,如何保证CSS样式不冲突?

在前端项目开发中,例如突然来了一个大项目,很可能就需要多人一起开发,领导说了,要快,要快,要快,你们给我快。然后下面大伙就一拥而上,干着干着发现,一更新代码&#xff0…

LiDAR360MLS 7.2.0 雷达点云数据处理软件功能介绍

新增模块和功能: 支持手持、背包数据的解算 SLAM解算成功率提升 SLAM解算效率提升 采集端与后处理端保持一致 赋色优化 新增平面图模块 新增平面图全自动矢量化功能 新增平面图矢量一键导出DXF功能 新增平面图正射影像一键导出功能 支持交叉、垂直绘制 支…

添加west扩展命令

使用west工具的帮助命令,west -h,不仅可以列出west工具的内置命令,也可以列举当前工程中实现的扩展命令,如build,flash等。 本文将介绍如何添加扩展命令。 west扩展命令的位置通过以下方式查找: 1. 首先找…

python-自幂数判断

[题目描述]: 自幂数是指,一个N 位数,满足各位数字N 次方之和是本身。例如,153153 是 33 位数,其每位数的 33 次方之和,135333153135333153,因此 153153 是自幂数;16341634 是 44 位数…

react的自定义组件

// 自定义组件(首字母必须大写) function Button() {return <button>click me</button>; } const Button1()>{return <button>click me1</button>; }// 使用组件 function App() {return (<div className"App">{/* // 自闭和引用自…

Springboot 通过SSE 实现实时消息返回

网上搜了好多都是用 SseEmitter 实现的,自己搭的demo确实也可以了,但是我项目里有一个过滤器,死活配置都不行,终于用google搜了一下,第一篇帖子便解决了这个问题,代码和大佬链接如下: https://github.com/CodingChaozhang/spring_boot_practice_demo/blob/master/springboot_s…

基于电荷的EPFL HEMT模型

来源&#xff1a;Charge-Based EPFL HEMT Model&#xff08;TED 19年&#xff09; 摘要 本文介绍了一种面向设计的、基于电荷的模型&#xff0c;用于直流操作下的AlGaAs/GaAs和AlGaN/GaN高迁移率场效应晶体管。该固有模型基于物理原理&#xff0c;不引入任何经验参数。核心概…

vuInhub靶场实战系列--prime:2

免责声明 本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关。 目录 免责声明前言一、环境配置1.1 靶场信息1.2 靶场配置 二、信息收集2.1 主机发现2.1.1 netdiscover2.1.2 nmap主机扫描2.1.3 arp-scan主机扫描 2.2 端口扫描…

Hadoop+Spark大数据技术 实验11 Spark 图

17周期末考试 重点从第五章 scala语言开始 比如&#xff1a;映射&#xff08;匿名函数&#xff09; 11.3.1创建属性图 import org.apache.spark.graphx._ import org.apache.spark.rdd.RDD //创建一个顶点集的RDD val users: RDD[(VertexId ,(String,String))] sc.paralle…

技术管理之巅—如何从零打造高质效互联网技术团队阅读体验

技术管理之巅—如何从零打造高质效互联网技术团队 《技术管理之巅&#xff1a;如何从零打造高质效互联网技术团队》是黄哲铿所著的一本书&#xff0c;致力于帮助技术管理者从零开始打造高效的互联网技术团队。该书分为多个章节&#xff0c;分别探讨了从团队文化建设到技术架构…

leetcode 所有可能的路径(图的遍历)

leetcode 链接&#xff1a; 所有可能的路径 1 图的基本概念 1.1 有向图和无向图 左边是有向图&#xff0c;右边是无向图。对于无向图来说&#xff0c;图中的边没有方向&#xff0c;两个节点之间只可能存在一条边&#xff0c;比如 0 和 1 之间的边&#xff0c;因为是无向图&am…

Virtualbox 安装 ubuntu + qemu

0. 前言 关于 Virualbox 安装虚拟机的优秀文章太多了&#xff0c;笔者主要是着重梳理一些安装小细节&#xff0c;利己利人&#xff01;&#xff01; 如果需要保姆式的安装教程&#xff0c;可以查看后续的参考链接。 1. VirtualBox 的安装 直接去官网搜索最近的软件即可&…

汇编:头文件

汇编头文件&#xff08;header files&#xff09;在汇编语言编程中类似于高层语言中的头文件&#xff0c;它们通常包含宏定义、常量定义、数据结构定义、函数声明以及其他在多个汇编源文件中共享的代码&#xff1b;使用头文件可以提高代码的可维护性和可读性&#xff0c;并使代…

IEDA 默认集成依赖概述

IEDA 默认集成依赖概述 目录概述需求&#xff1a; 设计思路实现思路分析 1.Developer Tools:GraalVM Native supportGraphQL DGs Code GenerationSpring Boot DevToolsLombokSpring Configuration ProcessorDocker Compose supportSpring Modulith 2.WebWebSpring WebSpring Re…

SmartEDA赋能学校教育:电子设计学习新篇章,让梦想触手可及!

在数字化时代&#xff0c;电子设计已成为科技创新的重要驱动力。然而&#xff0c;对于许多初学者和在校学生来说&#xff0c;电子设计的学习过程往往充满了挑战和困惑。幸运的是&#xff0c;随着SmartEDA的出现&#xff0c;这一局面正在发生深刻改变。SmartEDA不仅简化了电子设…

司法协助:跨国法律合作的桥梁

在全球化日益深入的今天&#xff0c;跨国法律事务的处理愈发频繁和复杂。司法协助&#xff0c;作为各国间在司法领域进行互助的重要机制&#xff0c;不仅关乎个案的公平正义&#xff0c;更是维护国际法治秩序的关键一环。那么&#xff0c;什么是司法协助&#xff1f;它又是如何…

2 程序的灵魂—算法-2.4 怎样表示一个算法-2.4.2 用流程图表示算法

流程图表示算法&#xff0c;直观形象&#xff0c;易于理解。 【例 2.6】将例 2.1 求 5!的算用流程图表示。 【例 2.7】将例 2.2 的算用流程图表示。 【例 2.8】将例 2.3 判定闰年的算用流程图表示。