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

news2024/11/18 21:51:17

一、封装

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

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

                   代码可读性更高(类是对象的模板)。
行为角度:向类外提供必要的功能,隐藏实现的细节。
        优势: 简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。
实现办法:变为私有成员
私有成员:无需向 类外 提供的成员(变量和方法),可以通过私有化进行屏蔽。
做法:命名使用 双下划线开头
私有成员的名称被修改为:类名__成员名,可以通过__dict__属性查看。
"""
    疫情信息管理系统V2
        封装
将不需要让类外访问的成员变为私有。
封装的时候站在使用者的角度进行考虑,
       即站在主程序的角度考虑View成员,
         站在View的角度考虑Model成员       
"""


class EpidemicModel:
    """
        数据模型
    """

    def __init__(self, region="", new=0, now=0, total=0, eid=0):
        self.region = region
        self.new = new
        self.now = now
        self.total = total
        self.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 = 1001

    def add_epidemic(self, info):
        """
            添加疫情信息
        :param info:EpidemicModel类型,新信息
        """
        # 设置自增长编号
        info.eid = self.__start_id
        self.__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.region

        for item in self.list_epidemic:
            if item.eid == new.eid:
                # item.region = new.region
                # item.new = new.new
                # item.now = new.now
                item.__dict__ = new.__dict__
                return True
        return False


view = 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): # 4
        self.name = name
        self.age = age

# 子类没有构造函数,直接使用父类构造函数
class Teacher(Person):
    pass

# 子类有构造函数,将覆盖父类构造函数
class Student(Person):
    # 子类构造函数参数:父类+子类
    def __init__(self,  name="", age=0, score=0): # 2
        super().__init__(name, age) # 3
        self.score = score


qtx = 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):  # 4
        self.name = name
        self.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 = x
        self.y = y

    # 返回新对象
    def __add__(self, other):
        # 函数可以根据传入的参数类型,决定行为
        if type(other) == Vector02:
            x = self.x + other.x
            y = self.y + other.y
        else:
            x = self.x + other
            y = self.y + other
        return Vector02(x, y)

    # 累加:返回旧对象
    def __iadd__(self, other):
        if type(other) == Vector02:
            self.x += other.x
            self.y += other.y
        else:
            self.x += other
            self.y += other
        return Vector02(self.x, self.y)

    def __sub__(self, other):
        # 函数可以根据传入的参数类型,决定行为
        if type(other) == Vector02:
            x = self.x - other.x
            y = self.y - other.y
        else:
            x = self.x - other
            y = self.y - other
        return 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))  # 2753663477888


v1 = 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 = region
        self.new = new
        self.now = now
        self.total = total
        self.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 = 1001

    def add_epidemic(self, info):
        """
            添加疫情信息
        :param info:EpidemicModel类型,新信息
        """
        # 设置自增长编号
        info.eid = self.__start_id
        self.__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.region

        for item in self.list_epidemic:
            if item.eid == new.eid:
                # item.region = new.region
                # item.new = new.new
                # item.now = new.now
                item.__dict__ = new.__dict__
                return True
        return False


view = 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 = x
        self.y = y

    def __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 = x
        self.y = y

    def __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.x

pos01 = 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 = region
        self.new = new
        self.now = now
        self.total = total
        self.eid = eid  # 操作全球唯一标识符的变量

    def __str__(self):
        return "%s地区的编号是%s,新增%s人,现有%s人,累计%s人" 
        % (self.region, self.eid, self.new, self.now, self.total)

    # self是列表中的元素
    # other参数eid
    def __eq__(self, other):
        return self.eid == other


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))
            # 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 = 1001

    def add_epidemic(self, info):
        """
            添加疫情信息
        :param info:EpidemicModel类型,新信息
        """
        # 设置自增长编号
        info.eid = self.__start_id
        self.__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 True
        return 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.region

        for item in self.list_epidemic:
            if item.eid == new.eid:
                # item.region = new.region
                # item.new = new.new
                # item.now = new.now
                item.__dict__ = new.__dict__
                return True
        return False


view = EpidemicView()
view.main()

MVC架构思路

 软件架构设计思路

 

class Vector2:

    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __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

v01 = Vector2(1, 2)
v02 = Vector2(2, 3)
print(v01 + v02) # v01.__add__(v02)

class Vector2:
#二维向量
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __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.x
        self.y += other.y
        return self

v01 = 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 = x
        self.y = y

    # 决定相同的依据
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
    
    # 决定大小的依据
    def __lt__(self, other):
        return self.x < other.x

v01 = 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.coloradmin.cn/o/898706.html

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

相关文章

工具推荐:Chat2DB一款开源免费的多数据库客户端工具

文章首发地址 Chat2DB是一款开源免费的多数据库客户端工具&#xff0c;适用于Windows和Mac操作系统&#xff0c;可在本地安装使用&#xff0c;也可以部署到服务器端并通过Web页面进行访问。 相较于传统的数据库客户端软件如Navicat、DBeaver&#xff0c;Chat2DB具备了与AIGC…

第58步 深度学习图像识别:Transformer可视化(Pytorch)

一、写在前面 &#xff08;1&#xff09;pytorch_grad_cam库 这一期补上基于基于Transformer框架可视化的教程和代码&#xff0c;使用的是pytorch_grad_cam库&#xff0c;以Bottleneck Transformer模型为例。 &#xff08;2&#xff09;算法分类 pytorch_grad_cam库中包含的…

在变暖的北极,冰冻的河岸可能会被更快地侵蚀

冷冻水槽实验揭示了多年冻土河岸侵蚀对水温、河岸粗糙度和孔隙冰含量的敏感性。 阿拉斯加胡斯利亚社区附近科尤库克河沿岸 1.5 米高的河岸照片。河流横向侵蚀永久冻土层&#xff0c;使冻土和沉积物暴露在相对温暖的水和气温下&#xff0c;导致其解冻。这张银行暴露显示了一层棕…

python入门知识:分支结构

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 1.内容导图 &#x1f447; &#x1f447; &#x1f447; 更多精彩机密、教程&#xff0c;尽在下方&#xff0c;赶紧点击了解吧~ python资料、视频教程、代码、插件安装教程等我都准备好了&#xff0c;直接在文末名片自…

MsrayPlus多功能搜索引擎采集软件

MsrayPlus多功能搜索引擎采集软件 摘要&#xff1a; 本文介绍了一款多功能搜索引擎软件-MsrayPlus&#xff0c;该软件能够根据关键词从搜索引擎中检索相关数据&#xff0c;并提供搜索引擎任务、爬虫引擎任务和联系信息采集三大功能。我们将分析该软件在不同领域的应用&#xf…

【实战】十一、看板页面及任务组页面开发(二) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(二十四)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表三、TS 应用&#xff1a;JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理七、Hook&…

Scratch 游戏 之 随机大地图生成教程

在很多生存 / 沙盒类游戏中&#xff0c;地图往往是随机生成的&#xff0c;例如&#xff1a;饥荒、我的世界等。那我们该如何在scratch中实现这一点呢&#xff1f; 在scratch中有两种办法可以实现——画笔和克隆体。我们这次先聊克隆体。 我们可以先将克隆体设置为方形的&#x…

快解析内网穿透便捷访问内网私有云

快解析内网穿透软件的首要优势在于其不改变企业现有IT架构的特点。传统的内网穿透解决方案常常需要对企业网络进行重构&#xff0c;这不仅增加了工作量&#xff0c;还可能带来不稳定的因素。而快解析则巧妙地绕过了这一问题&#xff0c;让您能够在保持原有网络设备和配置的前提…

【Unity每日一记】Physics.Raycast 相关_Unity中的“X光射线”

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

spss---如何使用信度分析以及案例分析

信度分析 问卷调查法是教育研究中广泛采用的一种调查方法&#xff0c;根据调查目的设计的调查问卷是问卷调查法获取信息的工具&#xff0c;其质量高低对调查结果的真实性、适用性等具有决定性的作用。 为了保证问卷具有较高的可靠性和有效性&#xff0c;在形成正式问卷之 前&…

Python基础知识:类的属性查找教程

目录标题 前言正文尾语 前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 正文 有需要python源码/安装包/教程/电子书/资料等 点击此处跳转文末名片免费获取 先从对象自己的名称空间找&#xff0c;没有则取类里找&#xff0c;如果类里也没有则程序报错 class Student1:# …

JS中对象数组深拷贝方法

structuredClone() JavaScript 中提供了一个原生 API 来执行对象的深拷贝&#xff1a;structuredClone。它可以通过结构化克隆算法创建一个给定值的深拷贝&#xff0c;并且还可以传输原始值的可转移对象。 当对象中存在循环引用时&#xff0c;仍然可以通过 structuredClone()…

【Hibench 】完成 HDP-Spark 性能测试

&#x1f341; 博主 "开着拖拉机回家"带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341; 希望本文能够给您带来一定的…

0基础学习VR全景平台篇 第87篇:智慧眼-公告有什么作用?

一、功能说明 公告&#xff0c;即政府、团体对有关事件或者行动发布的通告。公告内容由管理员在后台添加&#xff0c;智慧眼成员在场景中添加热点时可以选择引用此公告&#xff0c;引用后会在热点详情页中展示。 二、后台编辑界面 点击【新增】&#xff0c;填写公告的标题和…

[Raspberry Pi]如何用VNC遠端控制樹莓派(Ubuntu desktop 23.04)?

之前曾利用VMware探索CentOS&#xff0c;熟悉Linux操作系統的指令和配置運作方式&#xff0c;後來在樹莓派價格飛漲的時期&#xff0c;遇到貴人贈送Raspberry Pi 4 model B / 8GB&#xff0c;這下工具到位了&#xff0c;索性跳過樹莓派官方系統(Raspberry Pi OS)&#xff0c;直…

牛客OJ题 打印日期

⭐️ 题目描述 &#x1f31f; OJ链接&#xff1a;https://www.nowcoder.com/practice/b1f7a77416194fd3abd63737cdfcf82b?tpId69&&tqId29669&rp1&ru/activity/oj&qru/ta/hust-kaoyan/question-ranking 思路&#xff1a; 默认从一月的天数开始&#xff0c…

一键批量修改文件夹名称,中文瞬间变日语,轻松搞定重命名

大家好&#xff01;现在为了更好地适应全球化发展&#xff0c;许多人都有了海外交流、旅行、学习的需求。但是难免遇到一个问题&#xff1a;在电脑中的中文文件夹名称如何快速翻译成日语&#xff1f; 首先&#xff0c;第一步&#xff0c;我们需要打开文件批量改名&#xff0c;…

编译老版本c++程序 报错 msvcrt.dll 以及 0x000000 内存 不能为 “read“ 问题 已解决

一般 win10 编译 xp对应老版本软件 调试采用 虚拟机形式进行测试&#xff0c;但是虚拟机中&#xff0c;无独立显卡&#xff0c;运行程序提示有&#xff0c;无法调用动态库&#xff0c;或者 内存无法读取&#xff0c;炸一看以为 winxp32位 内存识别只能3.7G.其实是显存无法使用…

【C++】STL---list

STL---list 一、list 的介绍二、list 的模拟实现1. list 节点类2. list 迭代器类&#xff08;1&#xff09;前置&#xff08;2&#xff09;后置&#xff08;3&#xff09;前置- -、后置- -&#xff08;4&#xff09;! 和 运算符重载&#xff08;5&#xff09;* 解引用重载 和 …

七夕特辑——3D爱心(可监听鼠标移动)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…