zoukankan      html  css  js  c++  java
  • python基础之面向对象1

    一、面向对象VS面向过程

      1、面向过程

        

      2、面向对象

      

        

    二、类与对象

      1、类和对象

        (1)基本概念

          

           

        类和对象的内存图如下:

        

        

        

      2、实例成员

        (1)实例变量

          

        (2)实例方法:

          

      3、类成员:

        (1)类变量

          

         (2)类方法

            

      4、静态方法:

        

    三、基本代码:

        

    """
        面向对象:考虑问题,从对象的角度出发.
        类:模板  抽象
        对象:具体 
    """
    
    
    class Wife:
        """
            老婆
        """
    
        # 1.数据成员 姓名 年龄 性别 ...
        def __init__(self, name, age, sex):
            # self "自己",调用当前方法的对象
            print(id(self))
            self.name = name
            self.age = age
            self.sex = sex
    
        # 2.方法成员 做饭 ...
        def cooking(self):
            print(id(self))
            print(self.name + "做饭")
    
    
    # 创建对象(实例化)
    # 调用 __init__(self,name,age,sex) 方法
    w01 = Wife("丽丽", 21, "")
    print(id(w01))
    # 调用对象的方法 w01 将自身传入方法
    w01.cooking()
    
    
    w02 = Wife("芳芳", 22, "")
    w02.cooking()
    print(id(w02))
    
    # 在内存中,方法只有一份.而对象有多份.
    """
        实例成员
    """
    
    # 创建实例成员,可以不在类中.(在实际项目中,仍然会在__init__方法中)
    # class Wife01:
    #     pass
    #
    #
    # w01 = Wife01()
    # w01.name = "丽丽"
    # print(w01.name)
    # print(w01.__dict__)# 此时实例变量是:{'name': '莉莉'}
    #
    # w01 = Wife01()
    # print(w01.__dict__) # 此时实例变量是:{}
    
    
    class Wife02:
        def __init__(self,name):
            self.name = name
    
    w01 = Wife02("丽丽")
    w01.name = "莉莉"
    print(w01.__dict__)# 此时实例变量是:{'name': '莉莉'}
    print(w01.name)
    
    w01 = Wife02("丽丽")
    print(w01.__dict__)# 此时实例变量是:{'name': '丽丽'}
    
    
    # 创建实例成员,可以不在__init__中.(在实际项目中,仍然会在__init__方法中)
    class Wife03:
        def __init__(self,name):
            self.name = name
    
        def fun01(self):
            self.age = 10
            print("fun01执行喽")
    
    w01 = Wife03("丽丽")
    # 通过对象调用实例方法,会自动传递对象地址.
    w01.fun01()
    # 通过类名调用实例方法,
    Wife03.fun01(w01)
    print(w01.age)
    """
        类成员
    """
    class ICBC:
        """
            工商银行
        """
        # 类变量    相当于被大家共享的"饮水机",
        moneys = 9999999
    
        # 类方法
        @classmethod
        def print_total_moneys(cls):
            # print(ICBC.moneys)
            print("总行金额:",cls.moneys)
    
        # 实例方法
        def __init__(self,name,money):
            # 实例变量:相当于每个人的"杯子"
            self.money = money
            self.name = name
            # 从总行中,扣除当前支行的现金
            ICBC.moneys -= money
    
    i01 = ICBC("广渠门支行",100000)
    # 调用类变量
    # print("总行金额:",ICBC.moneys)
    # 调用类方法,此时会自动传递类名进入方法
    ICBC.print_total_moneys()
    
    i02 = ICBC("磁器口支行",100000)
    # print("总行金额:",ICBC.moneys)
    ICBC.print_total_moneys()
    """
        静态方法引入
        00   01   02    03
        10   11   12    13
        20   21   22    23
    
        需求:在某个元素基础上,获取每个方向,指定数量的元素.
              10               向右     3    --> 11 12  13
              21               向上     2    -->11   01
              .....
    """
    
    
    class Vector2:
        """
            向量
        """
    
        def __init__(self, x=0, y=0):
            self.x = x
            self.y = y
    
            # # 实例方法
            # def fun01(self):
            #     pass
            #
            # # 类方法
            # @classmethod
            # def fun02(cls):
            #     pass
            #
            # # 静态方法:得不到对象地址/也得不到类名
            # @staticmethod
            # def fun03():
            #     pass
    
    
    # v01 = Vector2()
    # v01.fun01()# 隐式传递对象地址
    #
    # Vector2.fun02()# 隐式传递类名
    #
    # Vector2.fun03()
    
    
    def right():
        return Vector2(0,1)
    
    
    def up():
        return Vector2(-1,0)
    
    # ...
    
    
    # 在某个元素基础上,获取每个方向,指定数量的元素.
    def get_elements(list_target, v_pos, v_dir, count):
        result = []
        for i in range(count):
            # 位置 += 方向
            # 1 0        0 1   --> 1 1
            # 1 1        0 1         1 2
            # 1 2        0 1         1 3
            v_pos.x += v_dir.x
            v_pos.y += v_dir.y
            result.append(list_target[v_pos.x][v_pos.y])
        return result
    
    
    list01 = [
        ["00", "01", "02", "03"],
        ["10", "11", "12", "13"],
        ["20", "21", "22", "23"],
    ]
    
    #  10               向右     3    --> 11 12  13
    # re01 = get_elements(list01,Vector2(1,0),Vector2(0,1),3)
    #  21               向上     2    -->11   01
    # re02 = get_elements(list01,Vector2(2,1),Vector2(-1,0),2)
    
    
    # 10               向右     3    --> 11 12  13
    re01 = get_elements(list01,Vector2(1,0),right(),3)
    print(re01)
    re02 = get_elements(list01,Vector2(2,1),up(),2)
    print(re02)

    五、实例:

      练习1

      

    """
        (1)学生student是一个类,具有姓名,年龄等数据;
        具有学习study,工作work等行为。
        对象:悟空同学,28岁。
              八戒同学,29岁。
    
    """
    class Student:
        """
            学生类
        """
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def study(self):
            print(str(self.age) + "学习")
    
        def work(self):
            print(self.name+"工作")
    
    # s01 悟空对象的地址
    s01 = Student("悟空",28)
    s02 = Student("八戒",29)
    
    # 通过对象地址,调用对象方法,会自动传递对象地址.
    s01.study()
    s02.work()

      练习2:

      

    # 1. 在控制台中输入3个敌人,存入列表.
    # 2. 将敌人列表输出(调用print_self)到控制台
    
    class Enemy:
        """
            敌人类
        """
        def __init__(self,name='',hp=0,atk=0,atk_speed=0):
            """
                构造函数
            :param name: 敌人姓名
            :param hp: 血量
            :param atk: 攻击力
            :param atk_speed:攻击速度
            """
            self.name = name
            self.hp = hp
            self.atk = atk
            self.atk_speed = atk_speed
    
        def print_self(self):
            """
                打印对象
            :return:
            """
            print(self.name,self.hp,self.atk,self.atk_speed,sep='--')
    
    
    def input_control(msg):
        """
            控制输入数据
        :param msg: 提示信息
        :return: 返回正确的录入值
        """
        while True:
            try:
                return int(input(msg))
            except:
                print('输入有误!')
    
    
    def get_enemy_list(n):
        """
            获取敌人列表
        :param n: 敌人个数
        :return: 敌人列表
        """
        result_list = []
        for i in range(n):
            enemy = Enemy()
            enemy.name = input('请输入姓名:')
            enemy.hp = input_control('请输入血量')
            enemy.atk = input_control('请输入攻击力')
            enemy.atk_speed = input_control('请输入攻击速度')
            result_list.append(enemy)
        return result_list
    
    
    def get_enemy_by_name(name_value):
        lst = []
        for item in enemy_list:
            if item.name == name_value:
                lst.append(item)
        for i in lst:
            i.print_self()
    
    
    
    enemy_list = get_enemy_list(3)
    for item in enemy_list:
        item.print_self()
    
    get_enemy_by_name('张三')

      

      练习3:

    """
        二维列表工具
    """
    
    
    class Vector2:
        """
            向量
        """
    
        def __init__(self, x=0, y=0):
            self.x = x
            self.y = y
    
        # 将函数转移到类中,就是静态方法.
        @staticmethod
        def right():
            return Vector2(0, 1)
    
        @staticmethod
        def up():
            return Vector2(-1, 0)
    
        @staticmethod
        def left():
            return Vector2(0, -1)
    
        @staticmethod
        def down():
            return Vector2(1, 0)
    
        @staticmethod
        def right_up():
            return Vector2(-1, 1)
    
    
    class DoubleListHelper:
        """
            二维列表助手类
                定义:在开发过程中,所有对二维列表的常用操作.
        """
    
        @staticmethod
        def get_elements(list_target, v_pos, v_dir, count):
            result = []
            for i in range(count):
                v_pos.x += v_dir.x
                v_pos.y += v_dir.y
                result.append(list_target[v_pos.x][v_pos.y])
            return result
    
    
    # 测试.............
    list01 = [
        ["00", "01", "02", "03"],
        ["10", "11", "12", "13"],
        ["20", "21", "22", "23"],
    ]
    
    # 10               向右     3    --> 11 12  13
    re01 = DoubleListHelper.get_elements(list01, Vector2(1, 0), Vector2.right(), 3)
    print(re01)
    
    # 练习1:在二维列表中,获取23位置,向左,3个元素.
    re02 = DoubleListHelper.get_elements(list01, Vector2(2, 3), Vector2.left(), 3)
    # 练习2:在二维列表中,获取02位置,向下,2个元素.
    re02 = DoubleListHelper.get_elements(list01, Vector2(0, 2), Vector2.down(), 2)
    # 练习3:在二维列表中,获取20位置,右上,2个元素.
    re02 = DoubleListHelper.get_elements(list01, Vector2(2, 0), Vector2.right_up(), 2)
    print(re02)

      练习4:

      

    """
        练习: 对象计数器 
             创建老婆类(名字...),随意实例化对象.
           统计老婆数量(定义方法)
             画出内存图
    """
    
    class Wife:
        # 计数器
        count = 0
    
        @classmethod
        def get_count(cls):
            return Wife.count
    
        def __init__(self,name):
            # 实例变量
            self.name = name
            # 统计
            Wife.count += 1
    
    w01 = Wife("王超")
    w02 = Wife("马汉")
    # 通过类名,访问类方法
    print(Wife.get_count())

      

         练习5:

          

    """
        以面向对象的思想,描述下列场景.
        提示:对象与对象数据不同,类与类行为不同.
      张三 教 李四 学习python
       李四  教 张三  玩游戏
       张三 工作 挣了8000元
       李四 工作 挣了3000元
    """
    
    class Person:
        def __init__(self, name):
            # 人的姓名
            self.name = name
            # 人会的所有技能
            self.__skills = []
            self.__total_money = 0
    
        # 只读属性
        @property
        def skills(self):
            # return self.__skills # 返回可变对象地址,意味着类外仍然可以操作可变对象
            return self.__skills[:] # 返回新的可变对象地址,意味着类外仍然操作的是新可变对象,不影响原对象.
            # 备注:每次通过切片返回新对象,都会另外开辟空间创建新对象,占用过多内存.
    
        # 只读属性
        @property
        def total_money(self):
            return self.__total_money
    
    
        @property
        def name(self):
            return self.__name
    
        @name.setter
        def name(self,value):
            self.__name = value
    
    
        def teach(self, person_other, str_skill):
            # person_other 的技能列表,增加str_skill
            person_other.__skills.append(str_skill)
            print(self.name, "教了", person_other.name, str_skill)
    
        def work(self, money):
            self.__total_money += money
            print(self.name, "工作挣了", money, "")
    
    
    zs = Person("张三")
    ls = Person("李四")
    # 张三 教 李四 学习python
    zs.teach(ls, "python")
    # 李四  教 张三  玩游戏
    ls.teach(zs, "游戏")
    
    zs.work(8000)
    ls.work(4000)
    
    #************************
    zs = Person("张三")
    # zs.skills = [] # 不能改
    # 如果skills属性,返回的是__skills,那么仍然可以操作私有列表
    #                     __skills[:],那么操作的是新列表
    zs.skills.append("python")
    print(zs.skills)

        练习6:

        

    """
        创建技能类(技能名称,冷却时间,持续时间,攻击距离......)
        要求:使用属性封装变量
       创建技能列表(技能对象的列表)
       -- 查找名称是"降龙十八掌"的技能对象
       -- 查找名称是持续时间大于10秒的的所有技能对象
       -- 查找攻击距离最远的技能对象
       -- 按照持续时间,对列表升序排列.
    """
    
    
    class SkillData:
        def __init__(self, name, cd, time, distance):
            self.name = name
            self.cd = cd
            self.time = time
            self.atk_distance = distance
    
        @property
        def name(self):
            return self.__name
    
        @name.setter
        def name(self, value):
            self.__name = value
    
        @property
        def cd(self):
            return self.__cd
    
        @cd.setter
        def cd(self, value):
            self.__cd = value
    
        @property
        def time(self):
            return self.__time
    
        @time.setter
        def time(self, value):
            self.__time = value
    
        @property
        def atk_distance(self):
            return self.__atk_distance
    
        @atk_distance.setter
        def atk_distance(self, value):
            self.__atk_distance = value
    
        def print_self(self):
            print(self.name, self.cd, self.time, self.atk_distance)
    
    
    list_skills = [
        SkillData("降龙十八掌", 60, 10, 5),
        SkillData("如来神掌", 50, 5, 15),
        SkillData("六脉神剑", 80, 20, 8),
        SkillData("一阳指", 20, 50, 15),
        SkillData("冷酷追击", 15, 30, 9),
    ]
    
    # -- 查找名称是"降龙十八掌"的技能对象
    for item in list_skills:
        if item.name == "降龙十八掌":
            item.print_self()
    
    # -- 查找名称是持续时间大于10秒的的所有技能对象
    result = []
    for item in list_skills:
        if item.time > 10:
            result.append(item)
    
    # -- 查找攻击距离最远的技能对象
    result = list_skills[0]
    for i in range(1, len(list_skills)):
        # 后面的技能对象
        if result.atk_distance < list_skills[i].atk_distance:
            result = list_skills[i]
            # result.atk_distance = list_skills[i].atk_distance
    
    result.print_self()
    
    # -- 按照持续时间,对列表升序排列.
    for r in range(len(list_skills) - 1):
        for c in range(r + 1, len(list_skills)):
            if list_skills[r].time  >  list_skills[c].time:
                list_skills[r],list_skills[c] =  list_skills[c],list_skills[r]
    
    
    # 请用调试,查看列表的取值.
    print(list_skills)

        

  • 相关阅读:
    Spring Cloud Consul Config 知识点
    RabbitMQ 的 docker 镜像使用
    Spring Cloud Config 知识点
    漫画:什么是服务熔断?
    Flux 和 Mono 的区别
    同时引入依赖:spring-cloud-starter-gateway 和 spring-boot-starter-web,报错
    Feign 报错:The bean 'service-producer.FeignClientSpecification', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled.
    Feign和OpenFeign的区别
    Maven 报错:Compilation of Maven projects is supported only if external build is started from an IDE.
    使用 application.properties 中配置的属性,举例:@Value("${server.port}")
  • 原文地址:https://www.cnblogs.com/yuxiangyang/p/10705065.html
Copyright © 2011-2022 走看看