Python系统学习1-9-类三之特征

一、封装

数据角度:将一些基本数据类型复合成一个自定义类型。

       优势:将数据与对数据的操作相关联。

                   代码可读性更高(类是对象的模板)。
行为角度:向类外提供必要的功能,隐藏实现的细节。
优势: 简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。
实现办法:变为私有成员
私有成员:无需向 类外 提供的成员(变量和方法),可以通过私有化进行屏蔽。
做法:命名使用 双下划线开头
私有成员的名称被修改为:类名__成员名,可以通过__dict__属性查看。
"""疫情信息管理系统V2封装
将不需要让类外访问的成员变为私有。
封装的时候站在使用者的角度进行考虑,即站在主程序的角度考虑View成员,站在View的角度考虑Model成员       
"""class EpidemicModel:"""数据模型"""def __init__(self, region="", new=0, now=0, total=0, eid=0):self.region = regionself.new = newself.now = nowself.total = totalself.eid = eid  # 操作全球唯一标识符的变量class EpidemicView:"""疫情视图"""def __init__(self):self.__controller = EpidemicController()def __display_menu(self):"""显示菜单"""print("按1键录入疫情信息")print("按2键显示疫情信息")print("按3键删除疫情信息")print("按4键修改疫情信息")def __select_menu(self):"""选择菜单"""number = input("请输入选项:")if number == "1":# 重点1:类中通过self调用self.__input_epidemic()elif number == "2":self.__display_epidemics()elif number == "3":self.__delete_epidemic()elif number == "4":self.__modify_epidemic()
def __input_epidemic(self):"""录入疫情信息"""# 重点3:每次录入新数据创建新Model对象# model = EpidemicModel(#     input("请输入疫情地区:"),#     int(input("请输入现有人数:")),#     int(input("请输入新增人数:")),#     int(input("请输入累计人数:")),# )# model = EpidemicModel(#     region=input("请输入疫情地区:"),#     now=int(input("请输入现有人数:")),#     new=int(input("请输入新增人数:")),#     total=int(input("请输入累计人数:")),# )model = EpidemicModel()model.region = input("请输入疫情地区:")model.new = int(input("请输入新增人数:"))model.now = int(input("请输入现有人数:"))model.total = int(input("请输入累计人数:"))self.__controller.add_epidemic(model)def __display_epidemics(self):"""显示所有疫情信息"""for item in self.__controller.list_epidemic:print("%s地区的编号是%s,新增%s人,现有%s人,累计%s人" % (item.region, item.eid, item.new, item.now, item.total))def __delete_epidemic(self):"""删除疫情,录入编号,传递给controller,显示结果"""eid = int(input("请输入需要删除的疫情编号:"))  # 将输入的编号转为int类型if self.__controller.remove_epidemic(eid):print("删除成功哦~")else:print("哦~不行")def __modify_epidemic(self):"""修改疫情信息,录入、传递、显示:return:"""model = EpidemicModel()model.eid = int(input("请输入需要需改的疫情编号:"))model.region = input("请输入疫情地区:")model.new = int(input("请输入新增人数:"))model.now = int(input("请输入现有人数:"))model.total = int(input("请输入累计人数:"))if self.__controller.update_epidemic(model):print("修改成功")else:print("需改失败")def main(self):"""入口哦"""while True:self.__display_menu()self.__select_menu()class EpidemicController:"""疫情控制器"""def __init__(self):self.list_epidemic = []  # type:list[EpidemicModel]self.__start_id = 1001def add_epidemic(self, info):"""添加疫情信息:param info:EpidemicModel类型,新信息"""# 设置自增长编号info.eid = self.__start_idself.__start_id += 1  # 为下一个数据可以使用不同数据# 添加到列表中self.list_epidemic.append(info)def remove_epidemic(self, eid: int):"""在列表中移除疫情信息:param eid: int类型,疫情编号:return: bool类型,True表达移除成功,False表达移除失败"""for i in range(len(self.list_epidemic)):if self.list_epidemic[i].eid == eid:del self.list_epidemic[i]return True  # 循环中途退出,返回成功return False  # 列表没有找到,则删除失败# remove内部还有层循环,所以带来二次查找# for item in self.list_epidemic:#     列表名.remove(item)def update_epidemic(self, new):"""更新疫情信息:param new: Model类型:return: bool类型"""# for i in range(len(self.list_epidemic)):#     self.list_epidemic[i].region = new.regionfor item in self.list_epidemic:if item.eid == new.eid:# item.region = new.region# item.new = new.new# item.now = new.nowitem.__dict__ = new.__dict__return Truereturn Falseview = EpidemicView()
print(view.__dict__)
view.main()

二、继承

1、继承方法

适用性:多个类有代码上的共性,且概念上统一

说明:子类直接拥有父类的方法

语法:

class 父类:def 父类方法(self):方法体
class 子类(父类):def 子类方法(self):方法体
儿子 = 子类()
儿子.子类方法()
儿子.父类方法()

演示:

class Person:def say(self):print("讲话")class Student(Person):def play(self):self.say()print("玩耍")class Teacher(Person):def teach(self):print("讲课")t = Teacher()
t.say()
p = Person()

 2、内置函数

isinstance(对象, 类型):该方法用来检查给定的对象是否是给定类型的实例或者是给定类型的任意

子类的实例,通常使用该方法进行对象类型校验。

issubclass(class: type, classinfo: Union[type, ...]),用来判断指定的两个类型之间的从属关系

如果【class】是【classinfo】的子类返回真(True),否则返回假(False)

type(o: object):传入一个【object】对象,返回一个类型,通常与object.__class__方法

的返回值相同

案例:

class Person:def say(self):print("讲话")class Student(Person):def play(self):self.say()print("玩耍")class Teacher(Person):def teach(self):print("讲课")t = Teacher()
t.say()
p = Person()
## 关系判定# isinstance(对象, 类型),返回指定对象是否是某个类的对象。# isinstance方法用来检查给定的对象是否是# 给定类型的实例或者是给定类型的任意子类的实例,# 通常使用该方法进行对象类型校验
# 老师对象 是 人类型  True  【人类型包含老师对象】
print(isinstance(t, Person))
# 人对象 是 人类型   True
print(isinstance(p, Person))
# 人对象 是 教师类型  False
print(isinstance(p, Teacher))# issubclass(类型,类型),返回指定类型是否属于某个类型
# issubclass(class: type, classinfo: Union[type, ...])
#           用来判断指定的两个类型之间的从属关系
# 如果【class】是【classinfo】的子类返回真(True),否则返回假(False)
# 老师类型 是 人类型  True
print(issubclass(Teacher, Person))
# 人类型 是 人类型   True
print(issubclass(Person, Person))
# 人类型 是 教师类型  False
print(issubclass(Person, Teacher))# type(o: object)
# 传入一个【object】类型,返回一个【type】对象,通常与object.__class__方法的返回值相同
# 老师对象的类型 是 人类型  False
print(type(t) == Person)
# 人对象的类型 是 人类型   True
print(type(p) == Person)
# 人对象的类型 是 教师类型  False
print(type(p) ==  Teacher)

 

 

3、继承数据

语法:
class 子类(父类):def __init__(self,父类参数,子类参数):super().__init__(参数) # 调用父类构造函数self.实例变量 = 参数

 说明:子类如果没有构造函数,将自动执行父类的,但如果有构造函数将覆盖父类的。此时必须通过super()函数调用父类的构造函数,以确保父类实例变量被正常创建。

"""继承数据
"""class Person:def __init__(self, name = "" , age = 0): # 4self.name = nameself.age = age# 子类没有构造函数,直接使用父类构造函数
class Teacher(Person):pass# 子类有构造函数,将覆盖父类构造函数
class Student(Person):# 子类构造函数参数:父类+子类def __init__(self,  name="", age=0, score=0): # 2super().__init__(name, age) # 3self.score = scoreqtx = Teacher("齐大胜", 22)  # Ctrl+P看提示,继承父类的init函数rc = Student("任聪", 34, 90)  # 1
print(rc.name)

相关知识

-- 父类(基类、超类)、子类(派生类)。

-- 父类相对于子类更抽象,范围更宽泛;子类相对于父类更具体,范围更狭小。

-- 单继承:父类只有一个(例如 JavaC#)。

-- 多继承:父类有多个(例如C++Python)。

-- Object类:任何类都直接或间接继承自 object 类。

三、多态

字面意思:对于一种行为有不同表现形态。

概念:对于父类的一个方法,在不同的子类上有不同体现。

说明:编码时调用父类方法,运行时传递子类对象执行子类方法。

1、重写的定义

 
            定义:在子类定义与父类相同的方法
            作用:改变父类行为,体现子类个性。

2、重写内置函数

定义: Python 中,以双下划线开头、双下划线结尾的是系统定义的成员。 我们可以在自定义类中
           进行重写,从而改变其行为。

(1)__str__函数 

__str__ 函数:将对象转换为字符串 ( 对人友好的 )
class Person(object):def __init__(self, name="", age=0):  # 4self.name = nameself.age = age# 当对象被打印时,自动执行def __str__(self):return f"{self.name}的年龄是{self.age}"wjs = Person("魏剑霜", 26)
# print函数内部,调用的是object类的__str__函数
print(wjs)

(2)__add__函数

被累加的数据:

        如果为可变数据:

                +=运算符会返回旧数据 调用__iadd__函数

                +运算符返回新数据 调用__add__函数

        如果为不可变数据 :

                +=,+ 都会返回新数据 调用__add__函数

案例1:

'''
被累加的数据:
如果为可变数据: +=运算符会返回旧数据 调用__iadd__函数+运算符返回新数据 调用__add__函数
如果为不可变数据 +=,+ 都会返回新数据 调用__add__函数
'''
# 可变数据
list01 = [10]
print(id(list01))  # 2397935506880
list01 += [20]
print(id(list01)) # 2397935506880# 不可变数据
tuple01 = (10)
print(id(tuple01)) # 140723445966912
tuple01 += (20)
print(id(tuple01)) # 140723445967552
print("-------")
# 面试题
a = 1
print(id(a))  # 140724735125280
a += 2     # a.__add__(2)
print(id(a)) # 140724735125408
a = a + 2  # a.__add__(2)
print(id(a))  # 140724735125344
b = [1]
print(id(b)) # 2632814702784
b += [2]    # b.__iadd__([2]) 2632812524224
print(id(b))
b = b + [2] # b.__add__([2]) 2632812524224
print(id(b))

案例2:

"""重写当打印自定义对象时,自动执行__str__函数自定义对象相加时,自动执行__add__函数--通过传入参数的类型决定行为自定义对象累加时,自动执行__iadd__函数--可变数据返回旧数据--不可变数据返回新数据,即自动执行__add__
"""class Vector02:def __init__(self, x ,y):self.x = xself.y = y# 返回新对象def __add__(self, other):# 函数可以根据传入的参数类型,决定行为if type(other) == Vector02:x = self.x + other.xy = self.y + other.yelse:x = self.x + othery = self.y + otherreturn Vector02(x, y)# 累加:返回旧对象def __iadd__(self, other):if type(other) == Vector02:self.x += other.xself.y += other.yelse:self.x += otherself.y += otherreturn Vector02(self.x, self.y)def __sub__(self, other):# 函数可以根据传入的参数类型,决定行为if type(other) == Vector02:x = self.x - other.xy = self.y - other.yelse:x = self.x - othery = self.y - otherreturn Vector02(x, y)def __str__(self):return f"x分量为:{self.x},y分量为{self.y}"v1 = Vector02(1, 2)
v2 = Vector02(3, 4)
v3 = v1 + v2   # v1.__add__(v2)
print(v3.__dict__)
print("v3:",v3)v4 = v1 + 3
print("v4:",v4)v5 = v4 - v1
print("v5:",v5)
print("____")
# 可变数据: +=运算符会返回旧数据 __iadd__
#           +运算符返回新数据 __add__
# 对于+=运算符,如果没有__iadd__ ,会自动调用__add__函数,否则优先调用__iadd__函数
v1 = Vector02(1, 1)
print(id(v1))  # 2753663477888
v1 += Vector02(2, 2)
print(id(v1))  # 2753663477888v1 = Vector02(1, 1)
print(id(v1))  # 2753663477888
v1 += 2
print(id(v1))  # 2753663477888

封装案例:

"""疫情信息管理系统V2封装
"""class EpidemicModel:"""数据模型"""def __init__(self, region="", new=0, now=0, total=0, eid=0):self.region = regionself.new = newself.now = nowself.total = totalself.eid = eid  # 操作全球唯一标识符的变量class EpidemicView:"""疫情视图"""def __init__(self):self.__controller = EpidemicController()def __display_menu(self):"""显示菜单"""print("按1键录入疫情信息")print("按2键显示疫情信息")print("按3键删除疫情信息")print("按4键修改疫情信息")def __select_menu(self):"""选择菜单"""number = input("请输入选项:")if number == "1":# 重点1:类中通过self调用self.__input_epidemic()elif number == "2":self.__display_epidemics()elif number == "3":self.__delete_epidemic()elif number == "4":self.__modify_epidemic()def __input_epidemic(self):"""录入疫情信息"""# 重点3:每次录入新数据创建新Model对象# model = EpidemicModel(#     input("请输入疫情地区:"),#     int(input("请输入现有人数:")),#     int(input("请输入新增人数:")),#     int(input("请输入累计人数:")),# )# model = EpidemicModel(#     region=input("请输入疫情地区:"),#     now=int(input("请输入现有人数:")),#     new=int(input("请输入新增人数:")),#     total=int(input("请输入累计人数:")),# )model = EpidemicModel()model.region = input("请输入疫情地区:")model.new = int(input("请输入新增人数:"))model.now = int(input("请输入现有人数:"))model.total = int(input("请输入累计人数:"))self.__controller.add_epidemic(model)def __display_epidemics(self):"""显示所有疫情信息"""for item in self.__controller.list_epidemic:print("%s地区的编号是%s,新增%s人,现有%s人,累计%s人" % (item.region, item.eid, item.new, item.now, item.total))def __delete_epidemic(self):"""删除疫情,录入编号,传递给controller,显示结果"""eid = int(input("请输入需要删除的疫情编号:"))  # 将输入的编号转为int类型if self.__controller.remove_epidemic(eid):print("删除成功哦~")else:print("哦~不行")def __modify_epidemic(self):"""修改疫情信息,录入、传递、显示:return:"""model = EpidemicModel()model.eid = int(input("请输入需要需改的疫情编号:"))model.region = input("请输入疫情地区:")model.new = int(input("请输入新增人数:"))model.now = int(input("请输入现有人数:"))model.total = int(input("请输入累计人数:"))if self.__controller.update_epidemic(model):print("修改成功")else:print("需改失败")def main(self):"""入口哦"""while True:self.__display_menu()self.__select_menu()class EpidemicController:"""疫情控制器"""def __init__(self):self.list_epidemic = []  # type:list[EpidemicModel]self.__start_id = 1001def add_epidemic(self, info):"""添加疫情信息:param info:EpidemicModel类型,新信息"""# 设置自增长编号info.eid = self.__start_idself.__start_id += 1  # 为下一个数据可以使用不同数据# 添加到列表中self.list_epidemic.append(info)def remove_epidemic(self, eid: int):"""在列表中移除疫情信息:param eid: int类型,疫情编号:return: bool类型,True表达移除成功,False表达移除失败"""for i in range(len(self.list_epidemic)):if self.list_epidemic[i].eid == eid:del self.list_epidemic[i]return True  # 循环中途退出,返回成功return False  # 列表没有找到,则删除失败# remove内部还有层循环,所以带来二次查找# for item in self.list_epidemic:#     列表名.remove(item)def update_epidemic(self, new):"""更新疫情信息:param new: Model类型:return: bool类型"""# for i in range(len(self.list_epidemic)):#     self.list_epidemic[i].region = new.regionfor item in self.list_epidemic:if item.eid == new.eid:# item.region = new.region# item.new = new.new# item.now = new.nowitem.__dict__ = new.__dict__return Truereturn Falseview = EpidemicView()
print(view.__dict__)
view.main()

(3)__eq__函数

自定义对象比较相同时,自动执行__eq__函数

如果没有__eq__函数,则默认按地址进行比较
自定义__eq__函数后,进行重写,此时根据内容进行比较
有__eq__函数,结果为True,否则为False

in,count,remove底层都是__eq__函数。

class Vector02:def __init__(self, x ,y):self.x = xself.y = ydef __str__(self):return f"x分量为:{self.x},y分量为{self.y}"# 判断相同def __eq__(self, other):# 默认:按地址比较# return id(self) == id(other)# 重写:按内容比较# if self.x == other.x and self.y == other.y:#     return True# return False# 优化重写:按内容比较return self.__dict__ == other.__dict__pos01 = Vector02(1, 1)
pos02 = Vector02(1, 1)
print(pos01 == pos02)  # False,两地址不同
# 等价于
print(pos01.__eq__(pos02))# 如果默认有__eq__,则按照内容比较
list01 = [10]
list02 = [10]
print(list01 == list02)list01 = [Vector02(1, 1),Vector02(2, 1),Vector02(3, 1),Vector02(4, 1),Vector02(2, 1),
]# 如果没有__eq__函数,则默认按地址进行比较
# 自定义__eq__函数后,进行重写,此时根据内容进行比较
# 有__eq__函数,结果为True,否则为False
print(Vector02(1, 1) in list01)
# in的内部执行也是使用__eq__函数一一比较
# Vector02(1, 1).__eq__Vector02(1, 1)
# Vector02(2, 1).__eq__Vector02(1, 1)
# Vector02(3, 1).__eq__Vector02(1, 1)
# Vector02(4, 1).__eq__Vector02(1, 1)
# Vector02(2, 1).__eq__Vector02(1, 1)# 有__eq__函数,结果为2,否则为0
print(list01.count(Vector02(2, 1)))
# Vector02(2, 1).__eq__Vector02(1, 1)
# Vector02(2, 1).__eq__Vector02(2, 1)
# Vector02(2, 1).__eq__Vector02(3, 1)
# Vector02(2, 1).__eq__Vector02(4, 1)
# Vector02(2, 1).__eq__Vector02(2, 1)
list01.remove(Vector02(3, 1))
# # Vector02(1, 1).__eq__Vector02(3, 1)
# # Vector02(2, 1).__eq__Vector02(3, 1)
# # Vector02(3, 1).__eq__Vector02(3, 1)
# # list01[3].__eq__Vector02(3, 1)
# # list01[4].__eq__Vector02(3, 1)

(4)__gt__函数

自定义对象比较大小时,自动执行__gt__函数

class Vector02:def __init__(self, x ,y):self.x = xself.y = ydef __str__(self):return f"x分量为:{self.x},y分量为{self.y}"def __eq__(self, other):return self.__dict__ == other.__dict__# 判断大小def __gt__(self, other):# 默认:按地址比较# return id(self) > id(other)# 重写:按内容比较return self.x > other.xpos01 = Vector02(2, 2)
pos02 = Vector02(1, 1)
print(pos01 > pos02)  # False,两地址不同list01 = [Vector02(1, 1),Vector02(2, 1),Vector02(3, 1),Vector02(4, 1),Vector02(2, 1),
]print(max(list01))
print(list01.index(Vector02(1, 1)))  # index元素索引,没有就会报错
list01.sort()  # 升序排列
list01.sort(reverse=True) # 降序排列
for item in list01:print(item)

(4)总结

打印自定义对象时,自动执行__str__函数

自定义对象相加时,自动执行__add__函数

        --通过传入参数的类型决定行为

自定义对象累加时,自动执行__iadd__函数

        --可变数据返回旧数据

        --不可变数据返回新数据,即自动执行__add__

自定义对象比较相同时,自动执行__eq__函数

自定义对象比较大小时,自动执行__gt__函数

使用重写思路后,案例优化为:
 

"""疫情信息管理系统V3重写
"""class EpidemicModel:"""数据模型"""def __init__(self, region="", new=0, now=0, total=0, eid=0):self.region = regionself.new = newself.now = nowself.total = totalself.eid = eid  # 操作全球唯一标识符的变量def __str__(self):return "%s地区的编号是%s,新增%s人,现有%s人,累计%s人" % (self.region, self.eid, self.new, self.now, self.total)# self是列表中的元素# other参数eiddef __eq__(self, other):return self.eid == otherclass EpidemicView:"""疫情视图"""def __init__(self):self.__controller = EpidemicController()def __display_menu(self):"""显示菜单"""print("按1键录入疫情信息")print("按2键显示疫情信息")print("按3键删除疫情信息")print("按4键修改疫情信息")def __select_menu(self):"""选择菜单"""number = input("请输入选项:")if number == "1":# 重点1:类中通过self调用self.__input_epidemic()elif number == "2":self.__display_epidemics()elif number == "3":self.__delete_epidemic()elif number == "4":self.__modify_epidemic()def __input_epidemic(self):"""录入疫情信息"""# 重点3:每次录入新数据创建新Model对象# model = EpidemicModel(#     input("请输入疫情地区:"),#     int(input("请输入现有人数:")),#     int(input("请输入新增人数:")),#     int(input("请输入累计人数:")),# )# model = EpidemicModel(#     region=input("请输入疫情地区:"),#     now=int(input("请输入现有人数:")),#     new=int(input("请输入新增人数:")),#     total=int(input("请输入累计人数:")),# )model = EpidemicModel()model.region = input("请输入疫情地区:")model.new = int(input("请输入新增人数:"))model.now = int(input("请输入现有人数:"))model.total = int(input("请输入累计人数:"))self.__controller.add_epidemic(model)def __display_epidemics(self):"""显示所有疫情信息"""for item in self.__controller.list_epidemic:# print("%s地区的编号是%s,新增%s人,现有%s人,累计%s人" % (item.region, item.eid, item.new, item.now, item.total))# print(10) # 10.__str__()# print("a") # "a".__str__()print(item)  # 打印Model对象,需要重写__str__def __delete_epidemic(self):"""删除疫情,录入编号,传递给controller,显示结果"""eid = int(input("请输入需要删除的疫情编号:"))  # 将输入的编号转为int类型if self.__controller.remove_epidemic(eid):print("删除成功哦~")else:print("哦~不行")def __modify_epidemic(self):"""修改疫情信息,录入、传递、显示:return:"""model = EpidemicModel()model.eid = int(input("请输入需要需改的疫情编号:"))model.region = input("请输入疫情地区:")model.new = int(input("请输入新增人数:"))model.now = int(input("请输入现有人数:"))model.total = int(input("请输入累计人数:"))if self.__controller.update_epidemic(model):print("修改成功")else:print("需改失败")def main(self):"""入口哦"""while True:self.__display_menu()self.__select_menu()class EpidemicController:"""疫情控制器"""def __init__(self):self.list_epidemic = []  # type:list[EpidemicModel]self.__start_id = 1001def add_epidemic(self, info):"""添加疫情信息:param info:EpidemicModel类型,新信息"""# 设置自增长编号info.eid = self.__start_idself.__start_id += 1  # 为下一个数据可以使用不同数据# 添加到列表中self.list_epidemic.append(info)def remove_epidemic(self, eid: int):"""在列表中移除疫情信息:param eid: int类型,疫情编号:return: bool类型,True表达移除成功,False表达移除失败"""if eid in self.list_epidemic:self.list_epidemic.remove(eid)return Truereturn False# remove内部源码如下:# for i in range(len(self.list_epidemic)):#     if self.list_epidemic[i].__eq__(eid):#         del self.list_epidemic[i]def update_epidemic(self, new):"""更新疫情信息:param new: Model类型:return: bool类型"""# for i in range(len(self.list_epidemic)):#     self.list_epidemic[i].region = new.regionfor item in self.list_epidemic:if item.eid == new.eid:# item.region = new.region# item.new = new.new# item.now = new.nowitem.__dict__ = new.__dict__return Truereturn Falseview = EpidemicView()
view.main()

MVC架构思路

 软件架构设计思路

 

class Vector2:def __init__(self, x, y):self.x = xself.y = ydef __str__(self):return "x是:%d,y是:%d" % (self.x, self.y)def __add__(self, other):return Vector2(self.x + other.x, self.y +other.yv01 = Vector2(1, 2)
v02 = Vector2(2, 3)
print(v01 + v02) # v01.__add__(v02)

class Vector2:
#二维向量def __init__(self, x, y):self.x = xself.y = ydef __str__(self):return "x是:%d,y是:%d" % (self.x, self.y)# + 创建新def __add__(self, other):return Vector2(self.x + other.x, self.y +other.y)# += 在原有基础上修改(自定义类属于可变对象)def __iadd__(self, other):self.x += other.xself.y += other.yreturn selfv01 = Vector2(1, 2)
v02 = Vector2(2, 3)
print(id(v01))
v01 += v02
print(id(v01))
print(v01)

 

 

 

class Vector2:"""二维向量"""def __init__(self, x, y):self.x = xself.y = y# 决定相同的依据def __eq__(self, other):return self.x == other.x and self.y == other.y# 决定大小的依据def __lt__(self, other):return self.x < other.xv01 = Vector2(1, 1)
v02 = Vector2(1, 1)
print(v01 == v02)  # True 比较两个对象内容(__eq__决定)
print(v01 is v02)  # False 比较两个对象地址list01 = [
Vector2(2, 2),
Vector2(5, 5),
Vector2(3, 3),
Vector2(1, 1),
Vector2(1, 1),
Vector2(4, 4),
]
# 必须重写 eq
print(Vector2(5, 5) in list01)
print(list01.count(Vector2(1, 1)))
# 必须重写 lt
list01.sort()
print(list01)

 

 

 

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

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

相关文章

【VRTK4.0运动专题】手柄控制物体移动和旋转

文章目录 原理预设体将两轴转化为位置向量或角度后&#xff0c;调用运动脚本的方法&#xff0c;对指定的物体进行移动或旋转 步骤1、将轴转化为位置向量或角度&#xff1a; 建轴转化预设体&#xff0c;关联两轴&#xff0c;2、准备带有要用方法的运动脚本&#xff1a; 建功能物…

在线图片怎么转换成PDF?在线图片转换成PDF步骤介绍

文件格式要转化不知道怎么办?想要网上下载文件格式转换软件&#xff0c;但是却不知道下载哪个好?今天小编小编就给大家分享一下靠谱的小圆象PDF转换器工具&#xff0c;想知道这款软件好不好用?在线图片怎么转换成PDF?那就进来看看吧。 在线图片怎么转换成PDF 小圆象PDF转换…

requests模板成功下载,但是不能在pycharm中运行

在做实验的过程中&#xff0c;需要用到requests&#xff0c;但是在pycharm中成功下载&#xff0c;仍然无法使用&#xff0c;找了很久&#xff0c;解决方法如下&#xff1a; 进入win中的命令提示符 下载requests模块 pip install requests输入python显示你的python的基本信息&…

什么是软件压力测试?软件压力测试工具和流程有哪些?

软件压力测试 一、含义&#xff1a;软件压力测试是一种测试应用程序性能的方法&#xff0c;通过模拟大量用户并发访问&#xff0c;测试应用程序在压力情况下的表现和响应能力。软件压力测试的目的是发现系统潜在的问题&#xff0c;如内存泄漏、线程锁、资源泄漏等&#xff0c;…

基于灵动微MM32F3270微控制器的监护仪

监护仪是各类医用电子仪器中应用极为普遍的一种。监护仪不仅可以提高护理工作的效率&#xff0c;更重要的是&#xff0c;它为更全面、更准确的掌握患者病情&#xff0c;提高医疗服务质量提供了更可靠的保障。 基于灵动微MM32F3270微控制器的监护仪&#xff1a; -信号采集&…

Fabric.js 元素选中状态的事件与样式

本文简介 带尬猴&#xff01; 你是否在使用 Fabric.js 时希望能在选中元素后自定义元素样式或选框&#xff08;控制角和辅助线&#xff09;的样式&#xff1f; 如果是的话&#xff0c;可以放心往下读。 本文将手把脚和你一起过一遍 Fabric.js 在对象元素选中后常用的样式设置…

Java IO流(五)Netty实战[TCP|Http|心跳检测|Websocket]

Netty入门代码示例(基于TCP服务) Server端 package com.bierce.io.netty.simple; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGro…

激活函数总结(十七):激活函数补充(PELU、Phish)

激活函数总结&#xff08;十七&#xff09;&#xff1a;激活函数补充 1 引言2 激活函数2.1 Parametric Exponential Linear Unit&#xff08;PELU&#xff09;激活函数2.2 Phish激活函数 3. 总结 1 引言 在前面的文章中已经介绍了介绍了一系列激活函数 (Sigmoid、Tanh、ReLU、…

自平衡性:保持数据结构稳定的关键

自平衡性是一种重要的数据结构属性&#xff0c;它确保在执行插入、删除等操作后&#xff0c;数据结构能够自动进行调整&#xff0c;以保持整体的平衡状态。平衡的数据结构可以提供更快的操作性能&#xff0c;避免极端情况下的低效操作&#xff0c;同时保持树或其他结构的整体稳…

Idea Maven 构建,运行Java程序,二次开发Jmeter

Idea Maven 构建 1. maven下载2. Idea 配置3. 配置Maven镜像4. 在Maven项目pom.xml中添加依赖5. 创建jar包&#xff0c;更新pom&#xff0c;执行代码 1. maven下载 【官网】https://maven.apache.org/download.cgi 【其他版本】https://dlcdn.apache.org/maven/maven-3/ 2. …

KubeSphere 社区双周报 | Java functions framework 支持 SkyWalking | 2023.8.4-8.17

KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过 commit 的贡献者&#xff0c;并对近期重要的 PR 进行解析&#xff0c;同时还包含了线上/线下活动和布道推广等一系列社区动态。 本次双周报涵盖时间为&#xff1a;2023.08.04-2023.…

Vant 4.6.4发布,增加了一些新功能,并修复了一些bug

导读Vant 4.6.4发布,增加了一些新功能&#xff0c;并修复了一些bug等。 新功能 feat(area-data): 更新芜湖的县区数据&#xff0c;由 nivin-studio 在 #12122 中贡献feat(Locale): 添加塞尔维亚语到国际化&#xff0c;由 RogerZXY 在 #12145 中贡献feat(ImagePreview): 添加 c…

matlab使用教程(22)—非线性优化函数的设置

1.设置优化选项 可以使用由 optimset 函数创建的 options 结构体来指定优化参数。然后&#xff0c;可以将 options 作为输入传递给优化函数&#xff0c;例如&#xff0c;通过使用以下语法调用 fminbnd x fminbnd(fun,x1,x2,options) 或使用以下语法调用 fminsearch x f…

C#与西门子PLC1500的ModbusTcp服务器通信4--搭建ModbusTcp客户端

1、客户端选择 客户端可以是一个程序或一个设备&#xff0c;这里我以C#WINFORM程序来实现客户机与PLC的Modbustcp服务器通信&#xff0c;开发环境是VS2019&#xff0c;.NET Framework版本是4.7.2 2、创建winform程序 3、引入Nmodbus4协议 找到项目&#xff0c;找到引用&…

IntelliJ IDEA maven配置,设置pom.xml的配置文件

IntelliJ IDEA项目&#xff0c;选择 文件 设置&#xff0c;弹窗 构建、执行、部署 构建工具 Maven就可以 maven配置好以后&#xff0c;在pom.xml的配置文件中就可以设置对应的jar包了&#xff0c;这样构建的时候自动需要的jar&#xff0c;在项目中导入即 需要的jar包设置在po…

大数据Flink(六十六):Flink的重要概念和小结

文章目录 Flink的重要概念和小结 一、​​​​​​​​​​​​​​数据流图(Dataflow Graph)

解锁ChatGLM-6B的潜力:优化大语言模型训练,突破任务困难与答案解析难题

解锁ChatGLM-6B的潜力&#xff1a;优化大语言模型训练&#xff0c;突破任务困难与答案解析难题 LLM&#xff08;Large Language Model&#xff09;通常拥有大量的先验知识&#xff0c;使得其在许多自然语言处理任务上都有着不错的性能。 但&#xff0c;想要直接利用 LLM 完成…

【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanelButton

说在前面 rust新手&#xff0c;egui没啥找到啥教程&#xff0c;这里自己记录下学习过程环境&#xff1a;windows11 22H2rust版本&#xff1a;rustc 1.71.1egui版本&#xff1a;0.22.0eframe版本&#xff1a;0.22.0上一篇&#xff1a;这里 update update实际上还是eframe::App的…

自研分布式IM-HubuIM RFC草案

HubuIM RFC草案 消息协议设计 基本协议 评估标准 【性能】协议传输效率&#xff0c;尽可能降低端到端的延迟&#xff0c;延迟高于200ms用户侧就会有所感知 【兼容】既要向前兼容也要向后兼容 【存储】减少消息包的大小&#xff0c;降低空间占用率&#xff0c;一个字节在亿…

最新AI系统ChatGPT程序源码/微信公众号/H5端+搭建部署教程+完整知识库

一、前言 SparkAi系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。 那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧&#xff01…