【Python 基础】Python全栈体系(六)

Python 基础

2. 继承
2.1 语法角度讲
2.1.1 继承方法
  • 代码:
class 父类:
	def 父类方法(self):
		方法体

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

儿子 = 子类()
儿子.子类方法()
儿子.父类方法()
  • 说明:
    • 子类直接拥有父类的方法.
2.1.2 内置函数
  • isinstance(对象, 类型)
    • 返回指定对象是否是某个类的对象。
  • issubclass(类型,类型)
    • 返回指定类型是否属于某个类型。
"""
    继承 - 行为
        财产:钱不用孩子挣,但是可以花.
        皇位:江山不用太子打,但是可以坐.
        代码:子类不用写,但是可以直接用.
"""


class Person:
    def say(self):
        print("说话")


class Student(Person):
    def study(self):
        print("学习")
        super().say()
    def say(self):
        print("说")


class Teacher(Person):
    def teach(self):
        print("教学")


p01 = Person()
# 父类对象,只能访问父类成员
p01.say()

s01 = Student()
# 子类对象,可以访问父类成员和本类成员
s01.say()
# s01.study()

# t01 = Teacher()
# 不能访问兄弟类成员
# t01.study()


# 内置函数
# isinstance   对象  是一种  类型
# 人对象 是一种 人类型
print(isinstance(p01, Person))  # True
# 学生对象 是一种 人类型
print(isinstance(s01, Person))  # True
# 老师对象 是一种 学生类型
print(isinstance(t01, Student))  # False
# 人对象 是一种 老师类型
print(isinstance(p01, Teacher))  # False

# issubclass   类型  是一种  类型
# 人类型 是一种 人类型
print(issubclass(Person, Person))  # True
# # 学生类型 是一种 人类型
print(issubclass(Student, Person))  # True
# # 老师类型 是一种 学生类型
print(issubclass(Teacher, Student))  # False
# # 人类型 是一种 老师类型
print(issubclass(Person, Teacher))  # False


# type 对象  是  类型
# 人对象 是 人类型
print(type(p01) == Person)  # True
# 学生对象 是 人类型
print(type(s01) == Person)  # False
# 老师对象 是 学生类型
print(type(t01) == Student)  # False
# 人对象 是 老师类型
print(type(p01) == Teacher)  # False
"""
    定义父类
        动物(行为:吃)
    定义子类
        狗(行为:跑)
        鸟(行为:飞)
    体会isinstance/issubclass/type
"""
class Animal:
    def eat(self):
        print("吃饭饭喽")

class Dog(Animal):
    def run(self):
        print("跑喽")

class Bird(Animal):
    def fly(self):
        print("飞喽")


d01 = Dog()
print(isinstance(d01,Dog))
print(isinstance(d01,Animal))

print(issubclass(Bird,Dog))
print(type(d01))
print(type(d01) == Animal)
2.1.3 继承数据
  • 代码
class 子类(父类):
 	def __init__(self,参数列表):
		super().__init__(参数列表)
		self.自身实例变量 = 参数
  • 说明
    • 子类如果没有构造函数,将自动执行父类的,但如果有构造函数将覆盖父类的。此时必须通过super()函数调用父类的构造函数,以确保父类实例变量被正常创建。
2.1.4 定义
  • 重用现有类的功能,并在此基础上进行扩展。
  • 说明:子类直接具有父类的成员(共性),还可以扩展新功能。
2.1.5 优点
  • 一种代码复用的方式。
2.1.6 缺点
  • 耦合度高:父类的变化,直接影响子类。
    在这里插入图片描述
"""
    继承 - 数据
"""


class Person:
    def __init__(self, name=""):
        self.name = name


class Student(Person):
    def __init__(self, name="", score=0):
        super().__init__(name)
        self.score = score


# 如果子类没有构造函数,直接使用父类构造函数
s01 = Student("悟空", 100)
print(s01.name)
"""
    定义父类
        车(数据:品牌,价格)
    定义子类
        电动车(数据:充电速度,电池容量)
    画出内存图
"""


class Car:
    def __init__(self, brand="", price=0):
        self.brand = brand
        self.price = price


class Electrocar(Car):
    def __init__(self, brand="", price=0,
                 charging_speed=0, battery_capacity=0):
        super().__init__(brand, price)
        self.charging_speed = charging_speed
        self.battery_capacity = battery_capacity


e01 = Electrocar("宝马", 300000, 60, 10000000)
"""
    重写:覆盖
        子类具有和父类名称相同的方法
        调用子类对象时,执行子类方法。(父类方法被覆盖,不执行)
"""


# 对象 --> 字符串
# __str__
class Wife(object):
    def __init__(self, name="", age=0):
        self.name = name
        self.age = age

    # 对象 --> 字符串(没有限制)
    def __str__(self):
        return "奴家%s今年%d岁啦" % (self.name, self.age)

    # 对象 --> 字符串(python语法)
    def __repr__(self):
        return "Wife('%s', %d)"% (self.name, self.age)


w01 = Wife("双儿", 22)
print(w01.name)
content = w01.__str__()
print(content)

code = w01.__repr__()
print(code)

# eval:将字符串作为python代码执行
print(eval("1+2*3"))
# print(eval(input()))

# 克隆对象
w02 = eval(w01.__repr__())
w01.age = 26
print(w02.age,w02.__str__)
2.2 设计角度讲
2.2.1 定义
  • 将相关类的共性进行抽象,统一概念,隔离变化。
2.2.2 适用性
  • 多个类在概念上是一致的,且需要进行统一的处理。
2.2.3 相关概念
  • 父类(基类、超类)、子类(派生类)。
  • 父类相对于子类更抽象,范围更宽泛;子类相对于父类更具体,范围更狭小。
  • 单继承:父类只有一个(例如 Java,C#)。
  • 多继承:父类有多个(例如C++,Python)。
  • Object类:任何类都直接或间接继承自 object 类。
"""
    设计思想 - 引入
        老张开车去东北
        变化点:飞机、火车、轮船...
"""


class Person:
    def __init__(self, name=""):
        self.name = name

    def go_to(self, vehicle):
        print("走喽")
        if type(vehicle) == Car:
            vehicle.run()
        elif type(vehicle) == Airplane:
            vehicle.fly()
class Car:
    def run(self):
        print("嘟嘟~")
class Airplane:
    def fly(self):
        print("嗖嗖~")
p01 = Person("老张")
c01 = Car()
a01 = Airplane()
p01.go_to(a01)

在这里插入图片描述

"""
    设计思想
"""


class Person:
    def __init__(self, name=""):
        self.name = name

    def go_to(self, vehicle):
        print("走喽")
        # 1. 调用交通工具(父)
        if not isinstance(vehicle,Vehicle):
            raise Exception("传入的必须是交通工具")

        vehicle.transport()


class Vehicle:
    """
        交通工具:隔离人与具体交通工具的变化
    """

    def transport(self):
        pass


# -------------------------------------
class Car(Vehicle):
    # 3. 重写
    def transport(self):
        print("嘟嘟~")


class Airplane(Vehicle):

    def transport(self):
        print("嗖嗖~")


p01 = Person("老张")
c01 = Car()
a01 = Airplane()
# 2. 创建子类对象
p01.go_to(c01)

在这里插入图片描述

3. 多态
3.3 内置可重写函数
  • Python中,以双下划线开头、双下划线结尾的是系统定义的成员。我们可以在自定义类中进行重写,从而改变其行为。
3.3.1 转换字符串
  • __str__函数:将对象转换为字符串(对人友好的)
  • __repr__函数:将对象转换为字符串(解释器可识别的)
3.3.2 运算符重载
  • 定义:让自定义的类生成的对象(实例)能够使用运算符进行操作。
3.3.3 算数运算符重载

在这里插入图片描述

3.3.4 复合运算符重载

在这里插入图片描述

3.3.5 比较运算符重载

在这里插入图片描述

"""
    运算符重载(重写)
        自定义对象使用python运算符
"""


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

    # <
    def __lt__(self, other):
        return self.x + self.y < other.x + other.y

    # ==
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y


pos = Vector2(1, 2)
dir = Vector2(0, 1)
# print(pos + dir)  # pos.__add__(dir)

# pos.x += dir.x
# pos.y += dir.y
pos += dir
# print(pos)

"""
# 创建了新对象
list01 = [1]
print(id(list01))
list01 = list01 + [2]
print(id(list01))

# 累加(在原有对象基础上增加)
list02 = [1]
print(id(list02))
list02 += [2]
print(id(list02))
"""

list01 = [
    Vector2(1, 2),
    Vector2(7, 8),
    Vector2(5, 6),
    Vector2(3, 4)
]

# sorted升序:内部在循环调用每个元素的__lt__
for item in sorted(list01):  #
    print(item)

#in 的内部也在循环调用每个元素的__eq__方法
print(Vector2(1, 2) in list01)# ?

# list01.remove(Vector2(1, 2))
# list01.count(Vector2(1, 2))
"""
    手雷爆炸,伤害玩家(扣血,碎屏)和敌人(扣血,头顶爆字)。
    变化点:鸭子,房子...
    写出体现三大特征的代码:
        封装:根据需求分解出手雷类,玩家类,敌人类
        继承:使用攻击目标隔离手雷与玩家,敌人
        多态:手雷调用攻击目标,在玩家和敌人对象中体现了不同效果
              玩家和敌人分别重写了攻击目标的受伤方法
"""


class Grenade:
    def explode(self, target):
        target.damage()


class AttackTarget:
    def damage(self):
        print("扣血")


# ---------------------
class Player(AttackTarget):
    def damage(self):
        super().damage()
        print("碎屏")


class Enemy(AttackTarget):
    def damage(self):
        super().damage()
        print("头顶爆字")

g01 = Grenade()
p01 = Player()
e01 = Enemy()
g01.explode(e01)

四、设计原则

1. 开-闭原则(目标、总的指导思想)
  • Open Closed Principle
  • 对扩展开放,对修改关闭。
  • 增加新功能,不改变原有代码。
2. 类的单一职责(一个类的定义)
  • Single Responsibility Principle
  • 一个类有且只有一个改变它的原因。
3. 依赖倒置(依赖抽象)
  • Dependency Inversion Principle
  • 客户端代码(调用的类)尽量依赖(使用)抽象。
  • 抽象不应该依赖细节,细节应该依赖抽象。
4. 组合复用原则(复用的最佳实践)
  • Composite Reuse Principle
  • 如果仅仅为了代码复用优先选择组合复用,而非继承复用。
  • 组合的耦合性相对继承低。
5. 里氏替换(继承后的重写,指导继承的设计)
  • Liskov Substitution Principle
  • 父类出现的地方可以被子类替换,在替换后依然保持原功能。
  • 子类要拥有父类的所有功能。
  • 子类在重写父类方法时,尽量选择扩展重写,防止改变了功能。
6. 迪米特法则(类与类交互的原则)
  • Law of Demeter
  • 不要和陌生人说话。
  • 类与类交互时,在满足功能要求的基础上,传递的数据量越少越好。因为这样可能降低耦合度。
    在这里插入图片描述
"""
    创建图形管理器:
        1. 记录所有图形
        2. 计算总面积
    图形:
        1. 矩形
        2. 圆形
        ...
    要求:
        增加新图形,管理器代码不变.

    画出设计图
    写出哪里体现了四大原则
        开闭原则:增加新图形,管理器代码不变.
        单一职责:Rectanlge负责矩形面积的算法,Circle负责圆形面积的算法,
                GraphicManager负责统一管理图形
        依赖倒置:图形管理器没有调用圆形、矩形算法,而是调用图形类。
        组合复用:图形管理器与具体的各种图形是组合关系。
"""


class GraphicManager:
    def __init__(self):
        self.__graphics = []

    def add_graphic(self, graphic):
        self.__graphics.append(graphic)

    def calculate_total_area(self):
        total_area = 0
        for item in self.__graphics:
            total_area += item.get_area()
        return total_area


class Graphic:
    def get_area(self):
        pass


# ------------------------
class Rectanlge(Graphic):
    def __init__(self, lenght=0, width=0):
        self.lenght = lenght
        self.width = width

    def get_area(self):
        return self.lenght * self.width


class Circle(Graphic):
    def __init__(self, radius=0):
        self.radius = radius

    def get_area(self):
        return 3.14 * self.radius ** 2


manager = GraphicManager()
manager.add_graphic(Rectanlge(2, 6))
manager.add_graphic(Circle(5))
print(manager.calculate_total_area())

第八章 信息管理系统(*)

在这里插入图片描述

一、需求

  • 实现对学生信息的增加、删除、修改和查询。

二、分析

界面可能使用控制台,也可能使用Web等等。

  1. 识别对象:界面视图类 逻辑控制类 数据模型类

  2. 分配职责:
    界面视图类:负责处理界面逻辑,比如显示菜单,获取输入,显示结果等。
    逻辑控制类:负责存储学生信息,处理业务逻辑。比如添加、删除等
    数据模型类:定义需要处理的数据类型。比如学生信息。

  3. 建立交互:
    界面视图对象 <----> 数据模型对象 <----> 逻辑控制对象

三、设计

  • 数据模型类:StudentModel
    • 数据:编号 id,姓名 name,年龄 age,成绩 score
  • 逻辑控制类:StudentManagerController
    • 数据:学生列表 __stu_list
    • 行为:获取列表 stu_list,添加学生 add_student,删除学生remove_student,修改学生update_student,根据成绩排序order_by_score。
  • 界面视图类:StudentManagerView
    • 数据:逻辑控制对象__manager
    • 行为:显示菜单__display_menu,选择菜单项__select_menu_item,入口逻辑main,
      输入学生__input_students,输出学生__output_students,删除学生__delete_student,修改学生信息__modify_student
"""
    步骤一:
        数据模型类:StudentModel
	        数据:姓名 name,年龄 age,成绩 score,编号 id
        逻辑控制类:StudentManagerController
            数据:学生列表 __stu_list
            行为:获取列表 stu_list,
                 添加学生 add_student
                 删除学生 remove_student(stu_id)
                 修改学生 update_student(new_stu)
                 根据成绩进行升序排列 order_by_score
    步骤二:
        界面视图类:StudentManagerView
            行为:
            显示菜单__display_menu,
            选择菜单项__select_menu_item,入口逻辑main,
            输入学生__input_students,
            显示学生信息__output_students
            删除学生信息__delete_student
            修改学生信息__modify_student
            根据成绩升序输出学生__output_students_order_by_score

"""


class StudentModel:
    """
        学生数据模型类
    """

    def __init__(self, name="", age=0, score=0, id=0):
        self.name = name
        self.age = age
        self.score = score
        self.id = id


class StudentManagerController:
    """
        学生管理控制器:主要负责业务逻辑处理
    """
    init_id = 1000

    @classmethod
    def __generate_id(cls, stu):
        stu.id = cls.init_id
        cls.init_id += 1

    def __init__(self):
        self.__stu_list = []

    @property
    def stu_list(self):
        return self.__stu_list

    def add_student(self, stu):
        """
            添加学生信息
        :param stu: 需要添加的学生对象
        """
        StudentManagerController.__generate_id(stu)
        self.__stu_list.append(stu)

    def remove_student(self, stu_id):
        """
            移除学生信息
        :param stu_id:需要移除的学生编号
        :return:移除是否成功
        """
        for item in self.__stu_list:
            if item.id == stu_id:
                self.__stu_list.remove(item)
            return True
        return False

    def update_student(self, new_stu):
        """
            修改学生信息
        :param new_stu:需要修改的学生信息
        :return:是否修改成功
        """
        for item in self.__stu_list:
            if item.id == new_stu.id:
                item.name = new_stu.name
                item.age = new_stu.age
                item.score = new_stu.score
                return True
        return False

    def order_by_score(self):
        """
            根据成绩升序排列
        :return:
        """

        for r in range(len(self.__stu_list) - 1):
            for c in range(r + 1, len(self.__stu_list)):
                if self.__stu_list[r].score > self.__stu_list[c].score:
                    self.__stu_list[r], self.__stu_list[c] = self.__stu_list[c], self.__stu_list[r]

# 测试
# controller = StudentManagerController()
# data01 = StudentModel("悟空", 23, 96)
# controller.add_student(data01)
# controller.add_student(StudentModel("八戒", 25, 65))
# # print(controller.remove_student(1006))
# # controller.update_student(StudentModel("孙悟空", 24, 97, 1000))
# controller.order_by_score()
# for item in controller.stu_list:
#     print(item.id, item.name)

class StudentManagerView:
    """
        学生管理视图:主要负责界面逻辑
    """

    def __init__(self):
        self.__controller = StudentManagerController()

    def __display_menu(self):
        print("1)添加学生信息")
        print("2)显示学生信息")
        print("3)删除学生信息")
        print("4)修改学生信息")
        print("5)根据成绩升序排列")

    def __select_menu(self):
        item = input("请输入选项:")
        if item == "1":
            self.__input_students()
        elif item == "2":
            self.__output_students()
        elif item == "3":
            self.__delete_student()
        elif item == "4":
            self.__modify_student()
        elif item == "5":
            self.__output_students_order_by_score()

    def main(self):
        """
            程序入口方法
        """
        while True:
            self.__display_menu()
            self.__select_menu()

    def __input_students(self):
        name = input("请输入学生姓名:")
        age = int(input("请输入学生年龄:"))
        score = int(input("请输入学生成绩:"))
        stu = StudentModel(name, age,score )
        self.__controller.add_student(stu)

    def __output_students(self):
        for item in self.__controller.stu_list:
            print("编号是:%d,姓名是%s,年龄是%d,成绩是%d." % (item.id, item.name, item.age, item.score))

    def __delete_student(self):
        stu_id = int(input("请输入编号:"))
        if self.__controller.remove_student(stu_id):
            print("删除成功")
        else:
            print("删除失败")

    def __modify_student(self):
        stu = StudentModel()
        stu.id = int(input("请输入需要修改的学生编号:"))
        stu.name = input("请输入需要修改的学生姓名:")
        stu.age = int(input("请输入需要修改的学生年龄:"))
        stu.score = int(input("请输入需要修改的学生成绩:"))
        if self.__controller.update_student(stu):
            print("修改成功")
        else:
            print("修改失败")

    def __output_students_order_by_score(self):
        self.__controller.order_by_score()
        self.__output_students()


view = StudentManagerView()
view.main()

在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柠檬小帽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值