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

news/2024/11/29 20:37:58/

一、封装

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

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

                   代码可读性更高(类是对象的模板)。
行为角度:向类外提供必要的功能,隐藏实现的细节。
优势: 简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。
实现办法:变为私有成员
私有成员:无需向 类外 提供的成员(变量和方法),可以通过私有化进行屏蔽。
做法:命名使用 双下划线开头
私有成员的名称被修改为:类名__成员名,可以通过__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.ppmy.cn/news/1057258.html

相关文章

MySQL中的数据类型

文章目录 1 常见的数据类型2 整数类型2.1 属性 M2.2 属性 UNSIGNED2.3 属性 ZEROFILL2.4 整数类型的适用场景 3 浮点类型4 定点类型5 位类型6 日期与时间类型6.1 YEAR 类型6.2 DATE 类型6.3 TIME 类型6.4 DATETIME 类型6.5 TIMESTAMP 类型 1 常见的数据类型 类型类型分类整数类…

20. 有效的括号(简单系列)

给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都…

免费照片转绘画风格软件-FotoSketcher

FotoSketcher一款免费照片转绘画风格软件&#xff0c;只需点击几下鼠标即可自动将照片转换为艺术作品。支持从铅笔素描到水彩画或油画、钢笔画、墨水画、抽象艺术和卡通画&#xff0c;有 20 多种不同的风格可供选择&#xff0c;工具还可以修改原始照片增强对比度、锐化、简化图…

共享数据-vue3

vuex方案 安装vuex4.x 两个重要变动&#xff1a; 去掉了构造函数Vuex&#xff0c;而使用createStore创建仓库 为了配合composition api&#xff0c;新增useStore函数获得仓库对象&#xff1b;获取路由对象使用useRouter global state 由于vue3的响应式系统本身可以脱离…

(四)Doceke安装MySQL镜像+Docker启动MySQL容器

Doceke安装MySQL镜像/Docker启动MySQL容器 一、doceke安装MySQL镜像 切换到root用户&#xff0c;su root 。 1、启动Docker 启动&#xff1a;sudo systemctl start docker 停止&#xff1a;systemctl stop docker 重启&#xff1a;systemctl restart docker 查看docker运行…

get和post请求的区别以及post请求的url参数问题

1.主要区别 1.GET请求方法有以下几个特点&#xff1a; 默认的请求方法&#xff1b;GET请求通常用于获取信息&#xff0c;所以应该是安全的、幂等的&#xff1b;请求数据表现在URL上&#xff0c;以名称/值的形式发送。对请求的长度有限制&#xff1b;在IE和Opera等浏览器会产生…

ubuntu下mysql

安装&#xff1a; sudo apt update sudo apt install my_sql 安装客户端&#xff1a; sudo apt-get install mysql-client sudo apt-get install libmysqlclient-dev 启动服务 启动方式之一&#xff1a; sudo service mysql start 检查服务器状态方式之一&#xff1a;sudo …

如何做好项目进度管理?来看这几个要点!

8个项目管理工具模板、60个项目管理甘特图标模板、赠送30本项目管理电子书https://download.csdn.net/download/XMWS_IT/19886618?spm1001.2014.3001.5503 项目进度管理是指在项目实施过程中&#xff0c;对各阶段的进展程度和项目最终完成的期限所进行的管理。其目的是保证项目…