zoukankan      html  css  js  c++  java
  • 0707 Python 类与对象

    1、什么是类

    • 人类、车类、鸟类、猴类、生物类
    • 是一群具有相同 特征 或者 相同行为的事物的一个统称,是抽象的
    • Python中的类可以类比为图纸(模子)
    • 类只有一个
    • 特征:一般是名词,特性, Python中称为属性
    • 行为: 一般为动作,Python中称为方法(类似于函数)

    2、什么是对象

    • 人类:男人 女人 性别不详的人
    • 鸟类:麻雀 孔雀 凤凰 鸵鸟
    • 对象是一个具体的存在:凤凰
    • 对象是由类创建的,并且具有类的特征和行为
    • 对象有很多个,可以使用类来创建多个对象
    • 每个对象之间,拥有不同的属性值
    • 每个对象的实例属性是独有的

    3.定义类class

    # 类名为大驼峰
    class PeopleInfo:
        """
        定义人类
        """
        # 类中称为方法
        # 类似于函数
        def __init__(self, name, age, sex):     # 构造方法, 构造器
            pass

    4.

    • 在类中创建的方法,如果带 self, 那么往往把它叫做实例方法
    • 创建对象,是一个实例化的过程
    • 使用 对象.方法名 来调用方法
    • 对象将自身, 自动传给了self, 所以不会报错, 在类里面, self 相当于one_person
    • 在类的外面创建属性, ---不推荐使用
    • 使用 对象.属性 = 属性值 类似于给变量赋值
    • 在类的外面如何调用属性
    • 使用 对象.属性 类似于获取变量
    class PersonInfo:  # 类相当于图纸(模板)
        """
        定义人类
        """
        def run(self):
            # self跟调用方法时的对象ID一致
            print("人会跑步")
    
        def eat(self):  # 在类中创建的方法, 如果带self, 那么往往把它叫做实例方式
            print("人会吃饭")
    
    
    one_person = PersonInfo()  # 创建对象(盖房子), 是一个实例化的过程
    print(f"one_person的ID为: {id(one_person)}")
    one_person.run()  # 使用 对象.方法名 来调用方法
    one_person.eat()  # 对象将自身, 自动传给了self, 所以不会报错, 在类里面, self相当于one_person
    
    # 在类的外面创建属性, ---不推荐使用
    # 使用 对象.属性 = 属性值    类似于给变量赋值
    one_person.name = "胡巴"
    one_person.age = 25
    one_person.height = 190
    # 在类的外面如何调用属性
    # 使用 对象.属性   类似于获取变量
    print(one_person.name)
    print(one_person.age)
    print(one_person.height)

    类属性:

    • 共有的特征, 那么叫做类属性
    • 在类的外面定义的是变量,但是在类名的下面。定义的变量,称为类属性,所以对象共有的特征

    类的初始化函数__init__:

    • 固定形式, 绝大多数情况下, 会使用__init__方法来创建属性,称为构造方法或者构造器, 推荐做法
    • 形参,由类名("雨欣") 来传参实参
    • 在构造方法下创建属性,写死:self.fair = "假发"
    • 一般在类的里面, 会使用 self.属性 来创建属性:self.name = name

    __str__:魔术方法

    • 如果使用print函数打印一个对象, 那么会自动调用__str__实例方法
    • _str__实例方法,需要返回一个字符串,否则会报错
    • 使用return来定义
    • def __str__(self):  # 魔术方法
          return "<{}>".format(self.name)

    在类中创建的方法,如果带 self, 那么往往把它叫做实例方法

    可以使用类来创建多个对象,每个对象之间,拥有不同的属性值,每个对象的实例属性是独有的

    class PersonInfo:   # 类相当于图纸(模板)
        """
        定义人类
        """
        # 共有的特征, 那么叫做类属性
        head = 1    # 在类的外面定义的是变量, 但是在类名的下面, 定义的变量, 称为类属性, 所以对象共有的特征
    
        def __init__(self, name, age, height):
            """
            固定形式, 绝大多数情况下, 会使用__init__方法来创建属性,称为构造方法或者构造器, 推荐做法
            :param name:形参,由类名("雨欣") 来传参实参
            :param age:形参,由类名(16) 来传参实参
            :param height:形参,由类名(170) 来传参实参
            """
            self.fair = "假发"     # 创建属性,写死
            self.name = name      # 一般在类的里面, 会使用 self.属性 来创建属性
            self.age = age
            self.height = height
            print(f"self的ID为: {id(self)}")
            # 在类的里面使用self.属性名, 能获取属性的值
            print("姓名: {}
    年龄: {}
    身高: {}".format(self.name, self.age, self.height))
    
        def run(self):
            # self跟调用方法时的对象ID一致,实例方法中,使用self.属性名 来调用
            # self.face = "瓜子"      # 实例方法中创建属性--不推荐
            print("{}会跑步".format(self.name))
    
        def eat(self):  
            # 在类中创建的方法, 如果带self, 那么往往把它叫做实例方法
            print("{}会吃饭".format(self.name))
    
        def info(self):
            # 在类的里面, 可以使用类名.类属性 来获取类属性的值
            # print("姓名: {}
    年龄: {}
    身高: {}
    脑袋个数: {}".format(self.name, self.age, self.height, PersonInfo.head))
            # 在类的里面, 可以使用self.类属性 来获取类属性的值
            print("姓名: {}
    年龄: {}
    身高: {}
    脑袋个数: {}".format(self.name, self.age, self.height, self.head))
    
        def __str__(self):  # 魔术方法
            # 如果使用print函数打印一个对象, 那么会自动调用__str__实例方法
            # 往往__str__实例方法, 需要返回一个字符串
            return "<{}>".format(self.name)
    
    
    # 可以使用类来创建多个对象
    # 每个对象之间, 拥有不同的属性值
    # 每个对象的实例属性是独有的
    one_person = PersonInfo("雨欣", 16, 180)   # 类名() 默认会调用__init__方法,实参
    two_person = PersonInfo("Sunny", 18, 185)
    
    # one_person.run()
    # two_person.run()
    # two_person.eat()
    print(one_person)
    print(two_person)
    
    # 在类的外面如何访问类属性?
    # 1. 类名.类属性
    print(PersonInfo.head)
    # 2. 对象.类属性
    print(one_person.head)
    print(two_person.head)
    
    # PersonInfo.info()     # 不能使用类名来调用实例方法
    # PersonInfo.name       # 不能使用类名来调用实例属性
    one_person.info()       # 可以使用对象名来调用实例方法

    5.类方法和静态方法

    类方法

    格式:

    @classmethod    # (译:可拉斯.蛮色的)装饰器,类方法来处理类属性的
        def angray(cls):    # 如果不加装饰器,默认创建实例方法
            cls.head = 2
            pass
    • 使用@classmethod来定义(译:卡拉斯.蛮色的)
      • 在类方法里面  调用  或  修改  类属性 -------cls.类属性
    • 在类中创建的方法, 如果带self, 那么它叫做实例方法
    • 在类的外面可以调用静态方法
      • 对象.静态方法
      • 类.静态方法
    • 在外面,来调实例属性
      • 对象.实例属性
    • 在外面,调用类属性
      • 对象.类属性
    • 在外面,调用类方法
      • 对象.类方法
    • 当对象调用类方法时, 会把对象所属的类ID自动赋值给cls
    • 在类的外面修改类属性--不推荐
      • 类名.类属性
    • 对象不能调用类外面的函数
      • 对象.函数名

    静态方法

    格式:

    @staticmethod   # (译:四大题刻.蛮色的 )定义的是静态方法, 静态跟类外面定义的函数几乎没有区别, 只不过是位置不同以
    def weather_forecase(motion):
        """
        播报天气
        在类的外面定义的一定是函数, 在类的里面定义的才是方法
        :return:
        """
        print("天气, 晴朗!")
        print("温度: 22°")
        print("适合出游")
    • 使用@staticmethod来定义
    • 在类的外面调用静态方法
      • 对象.静态方法  
      • 类.静态方法  
    • 在类的里面调用静态方法
      • self.静态方法  
    • 在类里面的类方法内调用静态方法
      • cls.静态方法  
    • 在类的里面可以调用类外面的函数

    6.类的内部和外部调用

    代码案例:

    class NumDeal:
    
        num_type = '数字类型'
        num_amount1 = 11
        num_amount2 = 33
    
        def __init__(self, num1, num2):
            self.num1 = num1
            self.num2 = num2
            print(f'类内部调用类方法nums_sum:{self.nums_sum()}')  # 类内部调用类方法,因为创建了两次实例对象,所以调用该方法时传入两个对象的实例变量值
            print(f'类内部调用实例方法nums_add:{self.nums_add()}')  # 类内部调用类方法,因为创建了两次实例对象,所以调用该方法时传入两个对象的实例变量值
            print(f'类的内部调用实例属性num1:{self.num1},num2:{self.num2}')  # 因为创建了两个实例化对象,所以会调用初始化函数两次,分别打印出两个对象分别传入的值
            print(f'类的内部调用类属性num_type:{self.num_type},num_amount1:{self.num_amount1},num_amount2:{self.num_amount2}')
    
        def nums_add(self):  # 实例方法
            return self.num1 + self.num2
    
        @classmethod  # 定义类方法需要用装饰器@classmethod
        def nums_sum(cls):      # 类方法
    
            return cls.num_amount1 + cls.num_amount2
    
    
    num_int = NumDeal(4, 5)
    num_float = NumDeal(4.1, 5.1)
    print('*'*30, 'num_int', '*'*30)
    print(f'类外边通过类实例对象num_int调用类属性:{num_int.num_type}')
    print(f'类外边通过类实例对象num_int调用实例属性num1:{num_int.num1},num2:{num_int.num2}')
    print(f'类外边通过类实例对象num_int调用实例方法nums_add(两个int类型数字相加结果):{num_int.nums_add()}')
    print(f'类外边通过类实例对象num_int调用类方法nums_sum():{num_int.nums_sum()}')
    print()
    print('*'*30, 'num_float', '*'*30)
    print(f'类外边通过类实例对象num_float调用类属性:{num_float.num_type}')
    print(f'类外边通过类实例对象num_float调用实例属性num1:{num_float.num1},num2:{num_float.num2}')
    print(f'类外边通过类实例对象num_float调用实例方法nums_add(两个float类型数字相加结果):{num_float.nums_add()}')
    print(f'类外边通过类实例对象num_float调用类方法nums_sum():{num_float.nums_sum()}')
    print()
    print('*'*30, 'NumDeal', '*'*30)
    print(f'类外边通过类名NumDeal调用类属性:{NumDeal.num_type}')
    # print(f'类外边通过类名NumDeal调用实例属性num1:{NumDeal.num1}')  # 会报错,说明不能用类名调用实例属性
    # print(f'类外边通过类名NumDeal调用实例方法nums_add():{NumDeal.add()}')#会报错,说明不能用类名调用实例方法
    # print(f'类外边通过类名NumDeal调用实例方法nums_add(:{NumDeal.nums_add(num_int)}')  # 可以在调用实例方法是传入类实例对象
    print(f'类外边通过类名NumDeal调用类方法nums_sum():{NumDeal.nums_sum()}')

    执行结果:

    类内部调用类方法nums_sum:44
    类内部调用实例方法nums_add:9
    类的内部调用实例属性num1:4,num2:5
    类的内部调用类属性num_type:数字类型,num_amount1:11,num_amount2:33
    类内部调用类方法nums_sum:44
    类内部调用实例方法nums_add:9.2
    类的内部调用实例属性num1:4.1,num2:5.1
    类的内部调用类属性num_type:数字类型,num_amount1:11,num_amount2:33
    ****************************** num_int ******************************
    类外边通过类实例对象num_int调用类属性:数字类型
    类外边通过类实例对象num_int调用实例属性num1:4,num2:5
    类外边通过类实例对象num_int调用实例方法nums_add(两个int类型数字相加结果):9
    类外边通过类实例对象num_int调用类方法nums_sum():44
    
    ****************************** num_float ******************************
    类外边通过类实例对象num_float调用类属性:数字类型
    类外边通过类实例对象num_float调用实例属性num1:4.1,num2:5.1
    类外边通过类实例对象num_float调用实例方法nums_add(两个float类型数字相加结果):9.2
    类外边通过类实例对象num_float调用类方法nums_sum():44
    
    ****************************** NumDeal ******************************
    类外边通过类名NumDeal调用类属性:数字类型
    类外边通过类名NumDeal调用类方法nums_sum():44

    1、实例属性

    在类的外面

      • 赋值(创建)
        • 对象.属性名-------不推荐  
        • 类.实例属性名 = 属性值
        • 错误用法,执行报错    
      • 调用
        • 对象.属性名      
        • 类.实例属性名 = 属性值
        • 错误用法,执行报错    

    在类的里面

      • 赋值(创建)
        • 使用__init__方法来给实例实例属性赋值  
        • self.属性名 = 属性值  
        • cls.实例属性名 = 属性值
        • 错误用法,执行报错    
      • 调用
        • self.属性名  
        • cls.实例属性名
        • 错误用法,执行报错    

    2、类属性

    在类的外面

      • 赋值(创建)
        • 类名.类属性名 = 类属性值  
        • 对象.类属性名 = 类属性值
        • 错误用法,执行报错    
      • 调用
        • 类名.类属性名  
        • 对象.类属性名  

    在类的里面

      • 赋值(创建)
        • 类名.类属性名 = 类属性值
        • cls.类属性名 = 类属性值
        • self.类属性名 = 类属性值
        • 错误用法,执行报错
      • 调用
        • 类名.类属性名
        • cls.类属性名
        • self.类属性名

    3、实例方法

    在类的外面

      • 调用
        • 对象.实例方法()  
        • 类名.实例方法()  
        • 错误用法,执行报错    

    在类的里面

      • 赋值(创建)
        • 类名.类属性名 = 类属性值
        • cls.类属性名 = 类属性值
        • self.类属性名 = 类属性值  
        • 错误用法,执行报错    
      • 调用
        • self.实例方法()  
        • 类名.实例方法()  
        • 错误用法,执行报错    
        • cls.实例方法()  
        • 错误用法,执行报错    

    4、类方法

    在类的外面

      • 调用
        • 类名.类方法()  
        • 对象.类方法()  

    在类的里面

      • 调用
        • 类名.类方法()  
        • self.类方法()  

    5、静态方法

    在类的外面

      • 调用
        • 类名.静态方法(参数)  
        • 对象.静态方法(参数)  

    在类的里面

      • 调用
        • 类名.静态方法(参数)  
        • self.静态方法(参数)  
        • cls.静态方法(参数)  

    7.类的继承、重写、拓展、超继承

    继承:

    • 子类可以直接调用继承的父类中的属性值:self/name
    • 使用类名(父类名) 来继承父类的所有方法, 私有方法和私用属性除外(__one_methond)
    • 被继承也可以叫做:父类、超类、基类
    • 继承父类的类叫做:子类

    重写:

    • 对父类方法的重写,如果定义了跟父类一样的方法名,那么会将父类同名的方法覆盖掉
    • 重写后,子类调用的是重写后的实例方法
    • super().父类方法,能够调用父类的方法,是Python3中的方法,重写

    拓展:

    • 拓展,,在父类的方法的基础上,新增内容;super().__init__ 代表父类,代表创建了对象调用了 init方法

    超继承:

    def info(self):     # 定义与父类同样的方法
        # super()能够调用父类的方法, 是Python3中的方法
        # super().info()    # 调用父类的方法
        print("工作: {}".format(self.job))    # 在本子类中添加新的内容
        # 即继承了父类中的方法,也添加了新的内容

    示例:

    class Animal(object):  # 如果一个类, 没有显示继承一个类, 那么默认会继承object(祖宗类)
        """
        定义动物类
        :object 写与不写都一样,如果一个类, 没有显示继承一个类, 那么默认会继承object(祖宗类)
        """
        def __init__(self, name, age, color):
            self.name = name
            self.age = age
            self.color = color
    
        def eat(self):
            print("{}需要吃东西".format(self.name))
    
        def drink(self):
            print("{}需要喝水".format(self.name))
    
        def run(self):
            print("{}会跑步".format(self.name))
    
        def sleep(self):
            print("{}需要睡觉".format(self.name))
    
        def info(self):
            print("姓名: {}
    年龄: {}
    颜色: {}".format(self.name, self.age, self.color))
    
    
    class Dog(Animal):
        """
        使用类名(父类名) 来继承父类的所有方法, 私有方法和私用属性除外(__one_methond)
        被继承的类也可以叫做:父类、超类、基类;继承父类的类叫做子类
        """
        def bark(self):
            print("{}会汪汪叫".format(self.name))
    
    
    class XiaoTianQuan(Dog):
    
        def __init__(self, name, age, color, job):
            # 拓展, 在父类的方法的基础上, 新增内容;super().__init__ 代表父类,代表创建了对象调用了 init方法
            # self.name = name
            # self.age = age
            # self.color = color
            super().__init__(name, age, color)
            self.job = job
    
        def fly(self):
            print("{}会飞".format(self.name))
    
        def sleep(self):
            # 对父类方法的重写,如果定义了跟父类一样的方法名, 那么会将父类同名的方法覆盖掉
            print("{}是神仙, 不需要睡觉".format(self.name))
    
        def info(self):
            # Python2中, 可以使用super(子类名, self).父类的方法
            # super(XiaoTianQuan, self).info()
            # super().父类方法,能够调用父类的方法, 是Python3中的方法,重写
            super().info()
            print("工作: {}".format(self.job))
    
    
    class Cat(Animal):
        def catch(self):
            print("{}会抓老鼠".format(self.name))
    
    
    if __name__ == '__main__':
        # taidi = Dog("泰迪", 1, '黑色')
        # taidi.weight = 2    # 动态创建属性, 比较少见, 也有应用场景
        # xiaotianquan = XiaoTianQuan("哮天犬", 1000, "金色")
        xiaotianquan = XiaoTianQuan("哮天犬", 1000, "金色", "守护天庭")
        # taidi.info()
        xiaotianquan.sleep()  # 重写方法:将父类的方法覆盖掉
        xiaotianquan.info()

    练习题:

    1.什么是类?什么是对象?

    什么是类?

      • 类 是对一群具有 相同特征 或者 行为 的事物的一个统称
      • 抽象的

    什么是对象?

      • 对象 是 由类创建出来的一个具体存在
      • 具体的

    2.类由哪几部分构成?

    • 特征 被称为 属性
      • 它是什么样的  
    • 行为 被称为 方法
      • 它可以做什么  

    3.列举几个生活中类和对象的例子

    • 建筑物图纸为类,建造出来的房子为对象
    • 狗为类,泰迪为对象
    • 测试为类,测试用例为对象

    4.类的设计原则

    请从类的命名、类中属性和方法来阐述

    • 类名
      • 满足大驼峰命名法
      • 分析 整个业务流程,找出其中的 名词
    • 属性
      • 这类事物具有什么样的特征
      • 找名词
    • 方法  
      • 这类事物具有什么样的行为  
      • 找动词  

    5.实例方法的特性?__init__方法的作用?

    类中实例方法的特性?

      • 第一个参数一定为self
      • 只能被对象调用
      • 对象.实例方法,会将对象自身传给self

    __init__方法的作用?

      • 创建属性并初始化
      • 类名(参数) 会调用__init__(self, 参数)方法

    6.实例方法与类方法的区别?

    实例方法

    • 只能被对象调用
    • 第一参数为self,在调用时会自动将对象自身传给self
    • 作用:处理实例属性
    • 在类外
      • 对象.实例方法(self, 参数)  
    • 在类里
      • self.实例方法(参数)  

    类方法

    • 能被对象、类来调用
    • 需要使用@classmethod装饰器以及第一个参数为cls
    • 在类外
      • 对象.类方法(cls, 参数) 会将对象的类传给cls  
      • 类.类方法(cls, 参数) 会将类传给cls  
    • 在类里
      • self.类方法(cls, 参数) 会将对象的类传给cls  
      • 类.类方法(cls, 参数) 会将类传给cls  
    • 作用:
      • 处理类属性  

    7.在类的里面和类的外面,调用实例方法、实例属性、类属性的方式?

    • 参考第6题,或上面总结的6.类的内外部调用

    8.__str__实例方法的作用?

    • 打印对象时会调用
    • 必须return 字符串

    9.编写如下程序,灰色的Tom猫,今年1岁,吃着美味的食物,喝着可口的饮料,非常享受的样子

    • a.根据以上信息,抽象出一个类
    • b.定义相关属性,并能在类的外面调用
    • c.定义相关方法,在方法中打印相应信息
    class Cat:
        """
        create a cat class
        """
        def __init__(self, name, color, age):
            """
            构造方法
            :param name: 姓名
            :param color: 颜色
            :param age: 年龄
            """
            self.name = name
            self.color = color
            self.age = age
            self.status = [] # 状态
    
        def eat(self):
            print("{}正在吃东西...".format(self.name))
            self.status.append("舔嘴巴")
    
        def drink(self):
            print("{}正在喝饮料...".format(self.name))
            self.status.append("喵喵喵...")
    
    
    tom = Cat("Tom", "灰色", 1)
    print("名字:{}
    颜色:{}
    年龄:{}".format(tom.name, tom.color, tom.age))
    tom.eat()
    tom.drink()
    print("{}很享受的样子,{}、{}".format(tom.name, *tom.status))

    10.类方法、静态方法分别是什么?有作用?如何定义?

    类方法是什么?

    • 针对 类 定义的方法

    作用?

    • 处理类属性

    如何定义?

    @classmethod 
    def 类方法名(cls): 
        pass
    • 需要修饰器 @classmethod 来标识
    • 第一个参数一般为 cls
    • 在类方法内部,可以直接使用 cls 访问 类属性 或者 调用类方法

    静态方法是什么? 作用?

    • 与对象和类没有直接关系的一段逻辑
    • 但在类中要调用某一个函数,为了类的封装性,往往会将类外面定义的函数拿到类里面来定义

    如何定义?

    @staticmethod 
    def 静态方法名(参数): 
        pass
    • 需要修饰器 @staticmethod 来标识
    • 在类里面和类外面,都能被对象和类来调用

    11.类方法、静态方法分别如何调用?

      答案参考题1

    12.什么是继承?有什么特性?

    什么是继承?

    • 获取已存在类的资源(方法和属性)

    有什么特性?

    • 能够继承父类的所有方法,私有方法除外

    13.编写如下程序,创建一个名为 Restaurant类,要求至少拥有饭店名和美食种类这两个特征。

    • a.需要创建一个方法来描述饭店名和美食种类相关信息
    • b.同时能够显示饭店营业状态(例如:正在营业)
    class Restaurant:
    
        def __init__(self, name, *args):
            self.name = name
            self.args = args
    
        def description(self, status):
            if status == 'OPEN':
                print('{}饭店营业正常营业'.format(self.name))
                for item in self.args:
                    print('美食种类有:{}'.format(item))
            elif status == 'CLOSED':
                print('{}饭店暂停营业,欢迎下次光临!'.format(self.name))
    
    
    if __name__ == '__main__':
        a = Restaurant('金手勺', '米饭', '馒头', '大饼')
        a.description('OPEN')
        a.description('CLOSED')

    方式二:

    class Restaurant:
        """
        创建一个餐馆类
        """
        def __init__(self, restaurant_name, cooking_type):
            self.restaurant_name, self.cooking_type = restaurant_name, cooking_type
    
        def describe_restaurant(self):
            print("*" * 46)
            print("{:^40s}
    ".format(self.restaurant_name))
            for key, item in enumerate(self.cooking_type, start=1):
                print("	{}.{}".format(key, item))
            print("	请点餐,祝您用餐愉快!")
            print("*" * 46)
    
        def open_restaurant(self):
            print("{},正在营业...".format(self.restaurant_name))
    
    
    cooking_types = ["北京烤鸭", "四川麻婆豆腐", "西湖醋鱼", "飞龙汤", "无为熏鸭", "东坡肉", "腊味合蒸", "辣子鸡", "东安子鸡", "清 蒸武昌鱼"]
    famous_restaurant = Restaurant("可优吃不腻餐馆", cooking_types)
    famous_restaurant.describe_restaurant()
    famous_restaurant.open_restaurant()

    14.编写如下程序,编写一个数学计算类,要求初始化方法带参数(传两个数字),能够实现加减乘除运算。

    class MathOperation:
        """
        数学运算类
        """
        def __init__(self, one_num, two_num):
            self.first_num, self.second_num = one_num, two_num
    
        def add(self):
            return self.first_num + self.second_num
    
        def minus(self):
            return self.first_num - self.second_num
    
        def multiply(self):
            return self.first_num * self.second_num
    
        def divide(self):
            try:
                return round(self.first_num / self.second_num, 2)   # 相乘之后四舍五入
            except ZeroDivisionError:
                # print("出现除0错误!")
                return ""
    
    
    if __name__ == '__main__':
        # one_number = 10
        # two_number = 0
        # math_operate = MathOperation(one_number, two_number)
        # print("{} + {} = {}".format(one_number, two_number, math_operate.add()))
        # print("{} - {} = {}".format(one_number, two_number, math_operate.minus()))
        # print("{} * {} = {}".format(one_number, two_number, math_operate.multiply()))
        # print("{} / {} = {}".format(one_number, two_number, math_operate.divide()))
    
        nums = (10, 0)      # 传入两个参数
        math_operate1 = MathOperation(*nums)    # *号代表解包:10和0
        print("{} + {} = {}".format(*nums, math_operate1.add()))
        print("{} - {} = {}".format(*nums, math_operate1.minus()))
        print("{} * {} = {}".format(*nums, math_operate1.multiply()))
        print("{} / {} = {}".format(*nums, math_operate1.divide()))

    15.编写如下程序,编写一个工具类和工具箱类,工具需要有的名称、功能描述、价格,工具箱能够添加工具、删除工具、查看工具,并且能获取工具箱中工具的总数。

    class Tool:
        """
        定义工具类
        """
    
        def __init__(self, name, desc, price):
            """ 构造方法
            :param name: 工具名称
            :param desc: 工具描述
            :param price: 工具价格
            :return: 无
            """
            self.name, self.desc, self.price = name, desc, price
    
        def describe_tool(self):
            """
            获取工具描述信息
            :return: """
            print("
    {:*^100}".format("开始描述"))
            print(f"名称:{self.name}
    功能:{self.desc}
    价格: {self.price}")
            print("{:*^100}
    ".format("结束描述"))
    
        def __str__(self):
            return "<{}>".format(self.name)
    
    
    class ToolPackage:
        """
        定义工具箱类
        """
        tools_count = 0
    
        def __init__(self, name):
            self.name = name
            self.all_tools = []  # 存放工具的列表
    
        def add(self, one_tool):
            """
            添加工具到工具箱中
            :param one_tool: Tool工具对象
            :return: """
            if isinstance(one_tool, Tool):
                self.all_tools.append(one_tool)
                self.modify_tool_count()
                print("成功添加【{}】到【{}】中!".format(one_tool.name, self.name))
            else:
                print("{}不是工具对象,无法添加!".format(one_tool))
    
        def has_tool(self, one_tool):
            """
            判断工具是否在工具箱中
            :param one_tool: Tool工具对象或者工具名
            :return: True or False
            """
            if isinstance(one_tool, Tool):  # 如果one_tool是工具对象
                return one_tool in self.all_tools  # 判断是否在工具箱中
            elif isinstance(one_tool, str):  # 如果是工具名,字符串
                for tool_obj in self.all_tools:
                    if one_tool == tool_obj.name:
                        return True
            return False
    
        def remove(self, one_tool):
            """
            删除工具
            :param one_tool: Tool工具对象或者工具名称
            :return:
            """
            if self.has_tool(one_tool):  # 如果要删除的工具存在
                if isinstance(one_tool, Tool):  # 如果one_tool为Tool工具对象
                    self.all_tools.remove(one_tool)
                else:  # 为工具名称字符串
                    for index, item in enumerate(self.all_tools):
                        if one_tool == item.name:  # 当前遍历的工具名为 one_tool
                            self.all_tools.pop(index)
                            break  # 删除之后,退出循环
            else:
                print("工具不存在,无法删除!")
    
        def search(self, one_tool):
            """
            根据工具对象或者工具名称查找工具
            :param one_tool: Tool工具对象或者工具名称
            :return:
            """
            if self.has_tool(one_tool):
                if isinstance(one_tool, Tool):  # 如果one_tool为Tool工具对象
                    one_tool.describe_tool()
                else:  # 为工具名称字符串
                    for index, item in enumerate(self.all_tools):
                        if one_tool == item.name:  # 当前遍历的工具名为 one_tool
                            self.all_tools[index].describe_tool()
                            break  # 找到工具之后,退出循环
            else:
                print("工具不存在!")
    
        @classmethod
        def modify_tool_count(cls):
            """
            类方法,每调用一次工具总数加一
            :return:
            """
            cls.tools_count += 1
    
        @classmethod
        def get_tool_count(cls):
            """
            类方法,获取工具箱中,工具总数
            :return:
            """
            return cls.tools_count
    
    
    hammer = Tool("锤子", "由金属或木头等材料做成的头和与之垂直的柄构成的敲击工 具。", 25.2)
    screwdriver = Tool("螺丝刀", "是一种用来拧转螺丝以使其就位的工具,通常有一个薄 楔形头,可插入螺丝钉头的槽缝或凹口内。", 5)
    saw = Tool("锯子", "用来把木料或者其他需要加工的物品锯断或锯割开的工具。", 12)
    electric_drill = Tool("电钻", "利用电做动力的钻孔机具。", 278)
    
    family_tool_package = ToolPackage("家用工具箱")
    # 将工具添加到工具箱中
    family_tool_package.add(hammer)
    family_tool_package.add(screwdriver)
    # 删除一个不存在的工具
    family_tool_package.remove(saw)
    # 按照工具的名字来删除一个工具
    family_tool_package.remove("锤子")
    # 再次添加工具
    family_tool_package.add(electric_drill)
    # 查询工具
    family_tool_package.search(saw)  # 查询不存在的工具
    family_tool_package.search(screwdriver)  # 查询已存在的工具
    family_tool_package.search("电钻")  # 通过工具名来查询工具
    # 获取工具总数
    print("{}中现在有【{}】件工具。".format(family_tool_package.name, family_tool_package.get_tool_count()))

    *******请大家尊重原创,如要转载,请注明出处:转载自:https://www.cnblogs.com/shouhu/,谢谢!!******* 

  • 相关阅读:
    [转]深度理解依赖注入(Dependence Injection)
    [转]控制反转(IOC)和依赖注入(DI)
    [转]依赖注入的概念
    [转]struct实例字段的内存布局(Layout)和大小(Size)
    异步编程模式
    HTTP协议返回代码含义
    [转]StructLayout特性
    Stack的三种含义
    FineUI登入的例子中遇到的一些问题
    编程以外积累: 如何给项目生成类似VS2008的说明文档
  • 原文地址:https://www.cnblogs.com/shouhu/p/12666891.html
Copyright © 2011-2022 走看看