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都是实例属性。

类属性示范:

python 复制代码
class Cat:
    black = "black cat detective"  # 这里black是类属性

2.根据对象创建类

格式如下:

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

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

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

对象名 . 新的属性值 = 值

python 复制代码
# 添加 颜色 属性
tom.color = '橘色'

完整栗子:

python 复制代码
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)。示范:

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

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

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

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

示范:

python 复制代码
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__()的方法删除调用的对象,来释放内存资源,这样的方法称为'析构'。

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

python 复制代码
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打印出调用的参数结果,例:

python 复制代码
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 中的运算符重载是一种特殊的多态性形式,运算符重载让我们能够对自定义的对象使用熟悉的运算符,如加法(+)、减法(-)、乘法(*)等。

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

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__方法,例:

python 复制代码
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)索引和分段重载

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

示例:

python 复制代码
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.

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

相关推荐
帅云毅14 分钟前
Web3.0的认知补充(去中心化)
笔记·学习·web3·去中心化·区块链
豆豆15 分钟前
day32 学习笔记
图像处理·笔记·opencv·学习·计算机视觉
逢生博客24 分钟前
使用 Python 项目管理工具 uv 快速创建 MCP 服务(Cherry Studio、Trae 添加 MCP 服务)
python·sqlite·uv·deepseek·trae·cherry studio·mcp服务
堕落似梦31 分钟前
Pydantic增强SQLALchemy序列化(FastAPI直接输出SQLALchemy查询集)
python
nenchoumi311936 分钟前
VLA 论文精读(十六)FP3: A 3D Foundation Policy for Robotic Manipulation
论文阅读·人工智能·笔记·学习·vln
凉、介42 分钟前
PCI 总线学习笔记(五)
android·linux·笔记·学习·pcie·pci
SuperSwaggySUP1 小时前
4/25 研0学习日志
学习
码起来呗1 小时前
基于SpringBoot的高校学习讲座预约系统-项目分享
spring boot·后端·学习
坐吃山猪1 小时前
Python-Agent调用多个Server-FastAPI版本
开发语言·python·fastapi
Yurko131 小时前
【C语言】全局变量、静态本地变量
c语言·学习