第33节课 面向对象编程

1. 面向对象编程基础

1.1 什么是面向对象编程

面向过程:执行者 耗时 费力 结果也不一定完美

面向对象:指挥者 省时 省力 结果比较完美

面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它使用"对象"来设计应用程序和软件。在Python中,一切皆为对象。面向对象编程的核心概念包括:类、对象、属性和方法。

面向对象思想就是把复杂的问题变成一个个会 “自己动” 的小模块。

比如你要模拟 “开车去超市” 的场景:

  • 汽车是一个 “对象”:它有自己的属性(颜色、油量、速度)和行为(加油、刹车、转向)。
  • 也是一个对象:有属性(名字、年龄)和行为(踩油门、打电话)。
  • 超市还是一个对象:有属性(地址、营业时间)和行为(开门、结账)。

**核心思路:**把万物当成 “会干活的小人”

重点:每个对象自己管自己的事,比如汽车自己处理 “加油” 的逻辑,你不用操心它内部怎么喷油 —— 这就是面向对象的核心思维。

如果不用面向对象,就像 “自己动手做所有事”——面向过程思想:

  • 比如模拟 “公司考勤系统”,传统方法要写一堆代码处理 “员工打卡”“计算工资”“生成报表”,所有逻辑混在一起,改一个小功能就得重写一大片。
  • 用面向对象后:
    • 每个员工是一个对象,自己管 “打卡记录”;
    • 财务是一个对象,自己算 “工资计算”;
    • 报表是一个对象,自己生成 “数据统计”。
      哪个模块出问题,直接改对应的对象就行,就像坏了的汽车零件直接换,不用拆整车。
# 面向过程的思想 计算矩形的面积
def 计算矩形面积(长度, 宽度):return 长度 * 宽度
print(计算矩形面积(10,10))# 面向对象的思想
class 矩形:def __init__(self,长度,宽度):self.长度 = 长度self.宽度 = 宽度def 计算面积(self):return self.长度 * self.宽度矩形A = 矩形(10,5)
矩形B = 矩形(100,2)
print(矩形A.计算面积())
print(矩形B.计算面积())

1.2 类和对象

类(Class)是对象的蓝图或原型,定义了对象的属性和行为。对象(Object)是类的实例,代表类定义的具体实体。

  • 类 = 蛋糕食谱
    食谱里写着 “需要面粉 200g、鸡蛋 3 个、糖 100g”(这是蛋糕的 “属性”),还写着 “混合材料→烤箱 180 度烤 30 分钟”(这是蛋糕的 “做法”,相当于对象的 “行为”)。
    重点:食谱本身不是蛋糕,而是告诉别人 “怎么做出一个蛋糕” 的模板。
  • 对象 = 按照食谱烤出来的草莓蛋糕
    你按食谱做出了一个具体的蛋糕,它的颜色是粉色(因为加了草莓酱),重量 500g,还能被吃掉(行为)。
    重点:这个蛋糕是 “实实在在存在的物体”,有自己独特的属性(比如别人的蛋糕可能是巧克力味,你的是草莓味)。
维度类(图纸)对象(实物)
是否真实存在不存在(是抽象的模板)存在(是具体的个体)
数量一个类可以对应多个对象每个对象都是类的一个 “实例”
属性与行为定义 “应该有什么”(比如手机类定义 “电量”)拥有 “具体的属性值”(比如某手机电量 80%)
作用用于创建对象,减少重复设计用于解决实际问题(比如用手机打电话)
class Dog:# 类属性 所有对象共享的集体属性 只有一份species = "犬科"# 构造函数 创建对象时自动调用,用于初始化对象的属性# self 区分对象的 看对象的地址 唯一的def __init__(self, name, age, sex="公"):print(f"{name}狗狗,正在成产中...")# 实例属性 成员变量 对象独有属性self.name = nameself.age = ageself.sex = sex# 实例方法 成员函数def bark(self):print(f'{self.name}正在汪汪叫!')# 实例方法 成员函数def get_info(self):print(f'一只名字叫{self.name}的狗,年龄{self.age}岁')def __del__(self):print(f"{self.name}狗狗,正在销户中...")# 创建Dog的对象 实际上引用的是构造函数 -> __init__()
dog1 = Dog("旺财", 3) # 存的是对象的地址 self
dog2 = Dog("狗蛋", 2, sex="母")print(dog1.name, dog1.age) # 实际上是用过地址找对象 从对象空间中找变量
print(dog2.name, dog2.age)print(dog1.species, dog2.species)dog1.bark()
dog1.get_info()
dog2.bark()
dog2.get_info()print(dog1.sex, dog2.sex)dog1.species = "人类"
print(dog1.species)
  • 类属性:所有对象共享的 “集体属性”
  • 实例属性:每个对象独有的 “个人属性”
  • 实例方法:对象能执行的 “个人行为”
类型定义位置归属特点
类属性类内部,方法外部所有对象共享,修改后全局生效
实例属性方法内(如__init__),用self.声明对象每个对象独立,修改不影响其他对象
实例方法类内部,第一个参数是self对象操作对象的实例属性,需通过对象调用

1.3 构造函数和析构函数

构造函数(__init__)在创建对象时自动调用,用于初始化对象的属性。析构函数(__del__)在对象被销毁时自动调用,用于执行清理操作。

构造函数:对象的 “出生证明办理器”

  • 就像 “新生儿出生时,医院会登记姓名、出生日期等信息”:
    • 构造函数的作用就是在对象创建时,给对象 “初始化” 必要的属性。
    • 没有构造函数,对象就像没有身份信息的 “黑户”,无法正常使用。

一般而言,只有当创建对象时才调用构造函数,对象创建之后,该对象就不应该再去调用构造函数了。

# 不推荐
dog1.__init__("哈哈", 12)
dog1.bark()
dog1.get_info()

析构函数:对象的 “注销手续办理器”

  • 就像 “人去世后,需要注销户口、收回身份证”:
    • 析构函数的作用是在对象被销毁时,执行清理工作(如释放内存、关闭文件等)。
    • 虽然不常用,但在处理资源占用时很重要(如数据库连接、文件句柄)。
类型方法名调用时机核心作用生活类比
构造函数__init__()创建对象时自动调用初始化对象属性,分配资源办出生证明、登记身份信息
析构函数__del__()对象被销毁时自动调用释放资源,执行清理工作办注销手续、回收资源
    def __init__(self, name, age, sex="公"):print(f"{name}狗狗,正在成产中...")# 实例属性 成员变量 对象独有属性self.name = nameself.age = ageself.sex = sexdef __del__(self):print(f"{self.name}狗狗,正在销户中...")

2. 面向对象的三大特性

2.1 封装

封装是将数据和方法捆绑在一起,对外部隐藏对象的内部细节,只暴露必要的接口。在Python中,可以使用下划线前缀来表示属性或方法的访问级别。

  • 公有属性:全家都能随便用的 “客厅”
  • 受保护属性:只给家人用的 “卧室”
  • 私有属性:禁止外人进入的 “保险柜”
属性类型标记方式访问限制生活类比
公有属性无前缀类内外均可自由访问、修改客厅(谁都能进)
受保护属性单下划线_建议类内部使用,外部可访问(靠约定)卧室(家人专用,外人少进)
私有属性双下划线__类外部无法直接访问,需通过方法操作保险柜(只有主人能开)
# 银行账户类
class BankAccount:def __init__(self, owner, balance=0):self.__owner = ownerself.__balance = balanceself.__password = "123456"# 存钱def deposit(self, amount):if amount > 0:self.__balance += amountprint(f"成功存入{amount}元!,余额{self.__balance}")else:print(f'存钱失败!存入钱数为负数{amount}')# 取钱def withdraw(self, amount):if 0 < amount <= self.__balance:self.__balance -= amountprint(f"成功取得{amount}元,余额{self.__balance}")else:print(f'余额不足或为负数{amount},余额{self.__balance}')# 查询余额def get_balance(self):print(self.__get_info())def __get_info(self):return f"账户名:{self.__owner},余额:{self.__balance}"account = BankAccount("张三", balance=100)
account.deposit(100)
account.deposit(-1000)
account.withdraw(50)
account.withdraw(1000)
account.get_balance()# print(account.owner)
# print(account.__balance)
# 错误操作
# account._balance = -100000000000
# print(account.__balance)
# print(account.__password)

2.2 继承

image-20250615170516029

继承允许一个类(子类)获取另一个类(父类)的属性和方法。这促进了代码重用并建立了类之间的层次关系。

用大白话来讲,继承就像 “子承父业”—— 子类可以直接 “继承” 父类的属性和方法,不用自己重新写一遍,既能减少重复代码,又能体现事物之间的 “所属关系 is - a”。

class Animal:def __init__(self, name, species, color):self.name = nameself.species = speciesself.color = colordef bark(self):print(f"这是动物{self.name}在说话")def eat(self):print(f'动物{self.name}在吃东西')def info(self):return f"{self.name},{self.species},{self.color}"class Dog(Animal):def __init__(self, name, species, color, breed):# 复用父类初始化的过程super().__init__(name, species, color)# 子类的特有属性初始化self.breed = breed# 重写从父类继承而来的函数def bark(self):super().bark()print(f"狗狗{self.name}{self.breed},在汪汪叫")def eat(self):print(f'狗狗{self.name},吃骨头')# 子类特有的行为def lookDoor(self):print("狗狗可以看门啊!")class Cat(Animal):def __init__(self, name, species, color):super().__init__(name, species, color)def bark(self):print(f"猫猫{self.name}{self.color},在喵喵叫")def eat(self):print(f'猫猫{self.name},吃鱼')# 子类特有的行为def zhuoJerry(self):print("猫猫可以捉老鼠")class Pig(Animal):def __init__(self, name, species, color, weight):super().__init__(name, species, color)self.weight = weightdef bark(self):print(f"猪猪{self.name}{self.weight},在哼哼叫")def eat(self):print(f'猪猪{self.name},吃西瓜')# 子类特有的行为def gongBaiCai(self):print("猪猪可以拱白菜")dog = Dog("旺财", "犬科", "黑色", "拉布拉多")
cat = Cat("咪咪", "猫科","鎏金黑")
pig = Pig("佩奇","猪科", "粉色",120)print(dog.info())
print(cat.info())
print(pig.info())
dog.bark()
cat.bark()
pig.bark()
dog.eat()
cat.eat()
pig.eat()
dog.lookDoor()
cat.zhuoJerry()
pig.gongBaiCai()animal = Animal("哈哈","嘻嘻","白色")
animal.bark()

多重继承

Python支持多重继承,一个类可以继承多个父类(最多有一个事物描述性的类Animal 体现is a关系,其他的体现like a 关系,功能的添加)。

class Flyable:def A(self):print("Flyable A")def fly(self):print("可以飞行")class Swimmable:def A(self):print("Swimmable A")def swim(self):print("可以游泳")class Animal:def __init__(self, name, species, color):self.name = nameself.species = speciesself.color = colordef bark(self):print(f"这是动物{self.name}在说话")def eat(self):print(f'动物{self.name}在吃东西')def info(self):return f"{self.name},{self.species},{self.color}"def A(self):print("Animal A")class Pig(Animal, Flyable, Swimmable):def __init__(self, name, species, color, weight):super().__init__(name, species, color)self.weight = weightdef bark(self):print(f"猪猪{self.name}{self.weight},在哼哼叫")def eat(self):print(f'猪猪{self.name},吃西瓜')# 子类特有的行为def gongBaiCai(self):print("猪猪可以拱白菜")def fly(self):print("猪猪在飞")def swim(self):print("猪猪在游泳")pig = Pig("佩奇", "猪科", "粉色", 120)pig.fly()
pig.swim()
pig.A()
print(Pig.__mro__)

当多个父类有相同的方法时,子类调用该方法会优先执行哪个父类的?这就是著名的菱形继承问题

Python 的 MRO(方法解析顺序):当调用子类的方法时,Python 会按照C3 线性化算法从左到右查找父类。

  • 多继承容易导致代码复杂,尽量用单继承或组合模式替代
  • 明确 MRO 顺序:用类名.__mro__查看方法解析顺序
  • 避免方法名冲突:如果多个父类有相同方法名,子类最好重写该方法,明确调用逻辑

组合模式举例

class 人类:def 说话(self):print("我是人类")class 机器:def 充电(self):print("正在充电")class 武器:def 发射导弹(self):print("发射导弹!")class 机甲战士:def __init__(self):self.人类特性 = 人类()self.机器特性 = 机器()self.武器特性 = 武器()def 执行任务(self):self.人类特性.说话()self.机器特性.充电()self.武器特性.发射导弹()高达 = 机甲战士()
高达.执行任务()

2.3 多态

多态是面向对象编程中最神奇的特性之一,就像《变形金刚》里的汽车人 —— 一辆卡车可以变成机器人,一架飞机也可以变成机器人,它们用不同的形态实现相同的「战斗」功能。在编程中,不同类型的对象可以响应同一个方法,但表现出不同的行为,这就是多态。

def animal_eat(animal):# 隐含 只是把它们当成Animal看待 调用的内容仅限于父类的内容或者重写父类的内容animal.eat()if isinstance(animal, Dog): # 把一个Animal当成一个具体的子类来看待 就可以调用子类特有的行为了animal.lookDoor()animal_eat(dog)
animal_eat(cat)
animal_eat(pig)

3. 高级面向对象概念

3.1 抽象类和接口

Python中可以使用abc模块创建抽象类和接口,强制子类实现特定的方法。

  • 抽象类:是一个「不完整的模板」,可以包含一些实现细节,子类需要补充剩余部分(抽象函数)。

    • 不能直接实例化,只能作为父类被继承。
    • 包含至少一个抽象方法(只有声明,没有实现,用@abstractmethod装饰器标记)。
    • 可以包含普通方法和属性,子类继承后可以直接使用。
  • 接口:是一个「纯粹的契约」,只规定方法签名,不包含任何实现,就像一份「必须遵守的规则清单」。

    • 只包含方法签名(没有实现),所有方法默认都是抽象的。
    • 不能包含属性,只有方法。
    • 一个类可以实现多个接口,就像「签署了多个契约」。
from abc import ABC, abstractmethod
# 包含了抽象函数的类 > 抽象类 不能直接创建对象
class Animal(ABC):def __init__(self, name, species, color):self.name = nameself.species = speciesself.color = color# 抽象函数:只保留函数声明 不保留函数体 抽象函数必须要被子类实现@abstractmethoddef bark(self):pass@abstractmethoddef eat(self):passdef info(self):return f"{self.name},{self.species},{self.color}"# 接口:只有抽象函数的抽象类
class Flyable(ABC):@abstractmethoddef fly(self):passclass Swimmable(ABC):@abstractmethoddef swim(self):passclass Dog(Animal):def __init__(self, name, species, color, breed):# 复用父类初始化的过程super().__init__(name, species, color)# 子类的特有属性初始化self.breed = breed# 重写从父类继承而来的函数def bark(self):super().bark()print(f"狗狗{self.name}{self.breed},在汪汪叫")def eat(self):print(f'狗狗{self.name},吃骨头')# 子类特有的行为def lookDoor(self):print("狗狗可以看门啊!")class Cat(Animal):def __init__(self, name, species, color):super().__init__(name, species, color)def bark(self):print(f"猫猫{self.name}{self.color},在喵喵叫")def eat(self):print(f'猫猫{self.name},吃鱼')# 子类特有的行为def zhuoJerry(self):print("猫猫可以捉老鼠")class Pig(Animal,Flyable, Swimmable):def __init__(self, name, species, color, weight):super().__init__(name, species, color)self.weight = weightdef bark(self):print(f"猪猪{self.name}{self.weight},在哼哼叫")def eat(self):print(f'猪猪{self.name},吃西瓜')# 子类特有的行为def gongBaiCai(self):print("猪猪可以拱白菜")def fly(self):print("猪猪可以飞")def swim(self):print("猪猪可以游泳")dog = Dog("旺财", "犬科", "黑色", "拉布拉多")
cat = Cat("咪咪", "猫科","鎏金黑")
pig = Pig("佩奇","猪科", "粉色",120)# 抽象类不能直接创建对象 本身就不具体
# a = Animal("嘻嘻","haha","123")def animal_eat(animal):# 隐含 只是把它们当成Animal看待 调用的内容仅限于父类的内容或者重写父类的内容animal.eat()if isinstance(animal, Dog): # 把一个Animal当成一个具体的子类来看待 就可以调用子类特有的行为了animal.lookDoor()animal_eat(dog)
animal_eat(cat)
animal_eat(pig)

到底什么是多继承:

(1)只有一个关系表示is a 要么继承一个描述性质的类/抽象类

(2)可以有多个关系表示参 can do ,实现多个接口而已 Flyable,Swimmable,就是给类后期添加额外的功能。拉布拉多天生是否可以导盲?黑背是否天生缉毒?

特性抽象类接口
能否实例化不能不能
方法实现可以包含普通方法和抽象方法只能包含抽象方法(默认全是抽象)
属性可以包含属性不能包含属性
继承 / 实现方式单继承(一个子类只能继承一个抽象类)多实现(一个类可以实现多个接口)
设计目的定义「是什么」(is-a 关系)定义「能做什么」(can-do 关系)

3.2 类方法和静态方法

Python中有三种类型的方法:实例方法、类方法和静态方法。

类方法和静态方法是面向对象编程中两种特殊的方法,它们与类的关系就像「家族顾问」和「家族工具」:

  • 类方法:绑定到类,能访问和修改类的属性,就像家族中负责管理族谱的顾问。

    • @classmethod装饰器声明,第一个参数必须是cls(代表类本身)。
    • 可以访问和修改类属性,也可以调用其他类方法,但不能直接访问实例属性。
    • 通过类名或实例名都能调用。
    • 类方法就像「家族会议」,参会者是家族成员(实例),但讨论的是家族共同事务(类属性)。
  • 静态方法:独立于类,不能访问或修改类的属性,就像家族共用的锤子,谁都能用但不隶属于任何人。

    • @staticmethod装饰器声明,没有类似selfcls的特殊参数。
    • 不能访问或修改类属性和实例属性,完全独立于类的状态。
    • 通过类名或实例名都能调用。
    • 静态方法就像「计算器」,可以被家族成员(实例)使用,但不记录任何家族信息。
def is_even(num):return num % 2 == 0print(is_even(10))class MathUtils:# 类属性pi = 3.14# 构造函数 创建对象时调用def __init__(self, value):# 实例属性 只能对象调用self.value = value# 实例方法 只能对象调用def add(self,x):return self.value + x# 类方法 和对象没关系了@classmethoddef get_pi(cls):return cls.pi@classmethoddef set_pi(cls, new_pi):cls.pi = new_pi# 静态方法 和类 对象 都没关系@staticmethoddef is_even(num):return num % 2 == 0
# 调用静态方法
print(MathUtils.is_even(10))math = MathUtils(10)
# 调用实例方法
print(math.add(5))
# 报错 通过类调用实例方法
# print(MathUtils.add(5))
# 对象可以访问类的内容
print(math.pi)
print(math.get_pi())# 通过类去调用类方法/属性
print(MathUtils.pi)
print(MathUtils.get_pi())# 对象也可以调用静态方法
print(math.is_even(10))
print(MathUtils.is_even(10))

生命周期从大到小分别为:静态 -> 类 -> 对象

小可以调大,大不能调小

如果当我们的类不需要创建对象时,而且还要调用其内容的话,可以考虑使用类方法/静态方法

特性类方法静态方法
装饰器@classmethod@staticmethod
第一个参数cls(代表类本身)无特殊参数
能否访问类属性不能
能否访问实例属性不能不能
设计目的操作类状态(如类属性)封装与类相关的通用功能(模块)

3.3 属性装饰器

使用@property装饰器可以将方法转换为属性,实现更好的封装。

属性装饰器(@property)是 Python 中一种优雅的语法糖,它能让方法像属性一样被访问,同时保留方法的计算逻辑或验证功能。简单来说,它把一个「函数调用」伪装成「属性访问」,让代码更简洁、更符合直觉。

# 银行账户类
class BankAccount:def __init__(self, owner, balance=0):self.__owner = ownerself.__balance = balanceself.__password = "123456"# Getter 仅用于获取实例属性的值# def get_owner(self):#     return self.__owner@propertydef owner(self):return self.__owner@propertydef balance(self):return self.__balance# Setter 用于给实例属性进行赋值# def set_balance(self, amount):#     if amount > 0:#         self.__balance = amount@balance.setterdef balance(self, value):if value > 0:self.__balance = valueaccount = BankAccount("张三", balance=100)
print(account.get_owner())
print(account.owner)
print(account.balance)
account.set_balance(500)
print(account.balance)
account.set_balance(-500)
print(account.balance)
account.balance = 100000
print(account.balance)
account.balance = -10000000
print(account.balance)

4.魔法函数

魔法函数(Magic Methods)是 Python 中一类特殊的方法,它们的名字以双下划线开头和结尾(如__init____str__)。这些方法不由开发者直接调用,而是在特定场景下被 Python 解释器自动触发,就像给类赋予了「隐藏超能力」。

通过实现魔法函数,你可以让自定义类支持 Python 的内置语法,例如:

  • 使用len(obj)获取对象长度 → 实现__len__
  • 使用str(obj)转换为字符串 → 实现__str__
  • 使用obj1 + obj2进行加法运算 → 实现__add__
  • 使用for item in obj进行迭代 → 实现__iter__

常见的魔法函数可分为以下几类:

  • 创建与销毁:__init__, __del__
  • 字符串表示:__str__, __repr__, __format__
  • 容器操作:__len__, __getitem__, __setitem__, __contains__
  • 比较运算:__eq__, __lt__, __gt__, __hash__
  • 运算符重载:__add__, __sub__, __mul__, __div__
  • 上下文管理:__enter__, __exit__
  • 可调用对象:__call__

对象转字符串

class Point:def __init__(self,x,y):self.x = xself.y = ydef __str__(self):return f"({self.x},{self.y})"p = Point(1,2)
# <__main__.Point object at 0x0000027EC14B1E80>
print(p) # 直接打印对象时 则调用__str__的返回结果

实现自定义列表

通过实现__len____getitem__,让类可以像列表一样被索引和遍历。

class 成绩册:def __init__(self):self.成绩 = []def 添加成绩(self,分数):self.成绩.append(分数)def __len__(self):return len(self.成绩)def __getitem__(self, 索引):return self.成绩[索引]
socres = 成绩册()
socres.添加成绩(85)
socres.添加成绩(90)
print(len(socres))
print(socres[0])
for socre in socres:print(socre)

实现自定义字典

通过__getitem____setitem____contains__实现字典功能。

class Config:def __init__(self):self.data = dict()def __getitem__(self, key):return self.data[key]def __setitem__(self, key, value):self.data[key] = valuedef __contains__(self, key):return key in self.datac = Config()
c['地址'] = "127.0.0.1"
c['端口'] = 8080
print(c['地址'])
print(c['端口'])

数值运算

实现__add____sub__等魔法函数,使对象支持加减乘除。

class Point:def __init__(self,x,y):self.x = xself.y = ydef __str__(self):return f"({self.x},{self.y})"# 定义两个对象相加时的逻辑def __add__(self, other):return Point( self.x + other.x, self.y + other.y)p1 = Point(1,2)
p2 = Point(3,4)
# <__main__.Point object at 0x0000027EC14B1E80>
print(p1) # 直接打印对象时 则调用__str__的返回结果
print(p2)
print(p1 + p2)

比较运算

实现__eq____lt__等魔法函数,使对象支持比较操作。

class FenShu:def __init__(self, fenzi,fenmu):self.fenzi = fenziself.fenmu = fenmudef __eq__(self, other):return self.fenzi == other.fenzi  and self.fenmu == other.fenmudef __lt__(self, other):return self.fenzi / self.fenmu < other.fenzi / other.fenmuf1 = FenShu(1,2)
f2 = FenShu(1,2)
# 此时的 == 默认比地址 除非重写__eq__
print(f1 == f2)
f3 = FenShu(2,5)
print(f3 < f1)
print(f3 > f1)
print(f3 == f1)

_(self):
return f"({self.x},{self.y})"
# 定义两个对象相加时的逻辑
def add(self, other):
return Point( self.x + other.x, self.y + other.y)

p1 = Point(1,2)
p2 = Point(3,4)

<main.Point object at 0x0000027EC14B1E80>

print(p1) # 直接打印对象时 则调用__str__的返回结果
print(p2)
print(p1 + p2)


**比较运算**实现`__eq__`、`__lt__`等魔法函数,使对象支持比较操作。```python
class FenShu:def __init__(self, fenzi,fenmu):self.fenzi = fenziself.fenmu = fenmudef __eq__(self, other):return self.fenzi == other.fenzi  and self.fenmu == other.fenmudef __lt__(self, other):return self.fenzi / self.fenmu < other.fenzi / other.fenmuf1 = FenShu(1,2)
f2 = FenShu(1,2)
# 此时的 == 默认比地址 除非重写__eq__
print(f1 == f2)
f3 = FenShu(2,5)
print(f3 < f1)
print(f3 > f1)
print(f3 == f1)

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

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

相关文章

Go 语言 里 `var`、`make`、`new`、`:=` 的区别

把 Go 语言 里 var、make、new、: 的区别彻底梳理一下。1️⃣ var 作用&#xff1a;声明变量&#xff08;可以带初始值&#xff0c;也可以不带&#xff09;。语法&#xff1a; var a int // 声明整型变量&#xff0c;默认值为 0 var b string // 默认值 ""…

计算机网络---IP(互联网协议)

一、IP协议概述 互联网协议&#xff08;Internet Protocol&#xff0c;IP&#xff09;是TCP/IP协议族的核心成员&#xff0c;位于OSI模型的网络层&#xff08;第三层&#xff09;&#xff0c;负责将数据包从源主机传输到目标主机。它是一种无连接、不可靠的协议&#xff0c;提供…

DataFun联合开源AllData社区和开源Gravitino社区将在8月9日相聚数据治理峰会论坛

&#x1f525;&#x1f525; AllData大数据产品是可定义数据中台&#xff0c;以数据平台为底座&#xff0c;以数据中台为桥梁&#xff0c;以机器学习平台为中层框架&#xff0c;以大模型应用为上游产品&#xff0c;提供全链路数字化解决方案。 ✨杭州奥零数据科技官网&#xff…

【工具】通用文档转换器 推荐 Markdown 转为 Word 或者 Pdf格式 可以批量或者通过代码调用

【工具】通用文档转换器 推荐 可以批量或者通过代码调用 通用文档转换器 https://github.com/jgm/pandoc/ Pandoc - index 下载地址 https://github.com/jgm/pandoc/releases 使用方法: 比如 Markdown 转为 Word 或者 Pdf格式 pandoc -s MANUAL.txt -o example29.docx …

【UEFI系列】Super IO

文章目录一、什么是Super IO二、Super IO的作用常见厂商三、逻辑设备控制如何访问SIO逻辑设备的配置寄存器具体配置数值四、硬件监控&#xff08;hardware monitor&#xff09;一、什么是Super IO Super Input/Output超级输入输出控制器。 通过LPC&#xff08;low pin count&a…

飞算 JavaAI 2.0.0 测评:自然语言编程如何颠覆传统开发?

一、前言 在AI技术高速发展的今天&#xff0c;编程方式正在经历一场革命。传统的“手写代码”模式逐渐被AI辅助开发取代&#xff0c;而飞算JavaAI 2.0.0的推出&#xff0c;更是让自然语言编程成为现实。 作为一名长期使用Java开发的程序员&#xff0c;我决定深度体验飞算Java…

Dubbo + zk 微服务

一、安装zk注册中心 win版本&#xff1a;windows环境下安装zookeeper教程详解&#xff08;单机版&#xff09;-CSDN博客 linux版本&#xff1a; 二、服务提供方搭建 引入dubbo和zk依赖 提供接口 使用注解方式实现接口级注册到zk&#xff0c;而springcloud是将服务注册到注册…

聆思duomotai_ap sdk适配dooiRobot

一、说明 1、duomotai_ap介绍 duomotai_ap是一个针对多模态开发板&#xff08;如 CSK6-MIX 开发板&#xff09;的大模型 AI 开发套件 SDK&#xff0c;主要用于开发语音、视觉等多模态 AI 应用。 2、dooiRobot介绍 基于Doly 机器人的经典外观设计&#xff0c;采用聆思CSK6011A…

Photoshop软件打开WebP文件格的操作教程

Photoshop软件打开WebP文件格的操作教程&#xff0c;好吧&#xff0c;这是英文原版&#xff1a; Photoshop 23.2 原生支持 WebP 格式&#xff0c;无需插件即可打开、编辑和保存 WebP 文件。用户可通过“文件 > 另存为副本”选择 WebP 格式&#xff0c;调整无损/有损压缩及质…

【数据结构】——顺序表链表(超详细解析!!!)

目录一. 前言二. 顺序表1. 顺序表的特点2. 代码实现三. 链表1. 单向链表代码实现2.双向链表代码实现四. 顺序表与链表的区别总结一. 前言 顺序表和链表是最基础的两种线性表实现方式。它们各有特点&#xff0c;适用于不同的应用场景。本文将详细介绍这两种数据结构的实现原理、…

GitHub的简单使用方法----(4)

在安装完git之后&#xff0c;桌面右键会出现两个git的选项第一个gui打开是这样的用户界面分别是新建仓库&#xff0c;克隆仓库&#xff0c;打开已经存在的仓库。tips:Git Gui 默认只能操作本地仓库——它本质上是一个图形化的“本地 Git 客户端”。 它本身不内置“下载远程仓库…

蓝桥杯----大模板

在写大模板之前&#xff0c;先讲一个函System_Init()&#xff0c;用于系统初始化关闭所有LED与外设&#xff0c;关闭所有LED就是传入0xff数据打开锁存器&#xff0c;关闭外设就是传入0x00打开锁存器。现在所有底层已经提供给大家了&#xff0c;先提供最简单版本的大模板&#x…

科技写作改革我见:取消参考文献,以点读率取代引证率!

科技写作改革我见&#xff1a;综述应取消参考文献&#xff0c;学术成就评估以点读下载率取代参考文献引证率&#xff01;李升伟 张君飞 韩若兰引言在当今信息爆炸的时代&#xff0c;科技写作作为知识传播的核心载体&#xff0c;其形式与评价体系正面临前所未有的挑战。传统…

【Altium designer】快速建立原理图工程的步骤

快速建立原理图工程的步骤产品规格书分析 整理产品需求&#xff0c;明确主控芯片、外围接口类型、总线频率、电源需求及隔离要求、PCB尺寸等关键信息。使用文本清单列出所有需求&#xff0c;确保无遗漏。硬件需求架构图绘制 根据需求说明书和收集的信息&#xff0c;使用VISIO绘…

Origin2025b安装包免费,附Origin 2025安装教程

老规矩先放链接&#xff1a;origin2025b安装包 有位小粉丝问我有没有Origin2025b的安装包&#xff0c;有的兄弟有的&#xff0c;只有你想不到&#xff0c;没有小兔找不到的软件。 这个origin是OriginLab公司开发的一个科学绘图、数据分析的软件&#xff0c;Origin支持各种各样…

【C++语法】输出的设置 iomanip 与 std::ios 中的流操纵符

文章目录【C语法】输出的设置 iomanip 与 std::ios 中的流操纵符1. iomanip 中的流操纵方法1.1 位宽操作类1.1.1 std::setw(x)1.1.2 std::setfill(c)1.1.3 std::left1.1.4 std::right1.1.5 std::internal1.2 小数操作类1.2.1 std::fixed1.2.2 std::setprecision(x)1.2.3 std::s…

go语言学习笔记-Map

map 是一种无序的基于 key-value 的数据结构&#xff0c;Go 语言中的 map 是引用类型&#xff0c;必须初始化 才能使用。 Go 语言中 map 的定义语法如下map[KeyType]ValueType常见两种创建方法1 使用map初始化var scoreMap make(map[string]int, 8) scoreMap["陈翔"…

芯片安全标准驱动库,筑牢芯片功能安全基石

随着整车控制器功能日益复杂&#xff0c;为满足越发严格的功能安全认证要求&#xff0c;项目开发人员需要采取相应的安全措施对系统中电子元器件的单点故障&#xff08;Singel Point Fault&#xff09;和潜在故障&#xff08;Latent Fault&#xff09;进行检测和管理&#xff0…

rn相关ScrollView

一&#xff1a;ScrollView的style和contentContainerStyle二&#xff1a;flex:1,和flexGrow:1用处内容将纵向空间占满

Spark Core 3.3.2 略讲~

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;大数据、Java、测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/…