• 05 面向对象


    前言

    此篇文章是我在B站学习时所做的笔记,部分为亲自动手演示过的,方便复习用。此篇文章仅供学习参考。


    提示:以下是本篇文章正文内容,下面案例可供参考

    面向对象

    基本的介绍

    面向对象是一个编程思想(写代码的套路)
    编程思想:

    1. 面向过程
    2. 面向对象

    以上两种都属于写代码的套路(方法) ,最终目的都是为了将代码书写出来,只不过过程和思考方法不太一样.

    • 面向过程
    1. 关注的是 具体步骤的实现, 所有的功能都自己书写
    2. 亲力亲为
    3. 定义一个个函数, 最终按照顺序调用函数
    • 面向对象
    1. 关注的是结果, 谁(对象) 能帮我做这件事
    2. 偷懒
    3. 找一个对象(), 让对象去做

    类和对象

    面向对象的核心思想是 找一个对象去帮我们处理事情
    在程序代码中 对象是由 类 创建的

    类和对象,是 面向对象编程思想中非常重要的两个概念

    1. 抽象的概念, 对 多个 特征和行为相同或者相似事物的统称
    2. 泛指的(指代多个,而不是具体的一个)
    • 对象
    1. 具体存在的一个事物, 看得见摸得着的
    2. 特指的,(指代一个)

    苹果 —> 类
    红苹果 ----> 类
    张三嘴里正在吃的那个苹果 —> 对象

    类的组成

    1, 类名 (给这多个事物起一个名字, 在代码中 满足大驼峰命名法(每个单词的首字母大写))
    2, 属性 (事物的特征, 即有什么, 一般文字中的名词)
    3, 方法 (事物的行为, 即做什么事, 一般是动词)
    类的抽象(类的设计)
    类的抽象,其实就是找到 类的 类名, 属性 和方法

    在这里插入图片描述
    类名: 人类(Person, People)
    属性: 名字(name), 年龄(age), 身高(height)
    方法: 跑步(run) 吃(eat)
    在这里插入图片描述
    类名: 狗类(Dog)
    属性: 颜色(color) , 名字(name)
    方法: 汪汪叫 (bark), 摇尾巴(shake)

    面向代码的步骤

    1. 定义类, 在定义类之前先设计类
    2. 创建对象, 使用第一步定义的类创建对象
    3. 通过对象调用方法

    面向对象基本代码的书写

    1. 定义类
      先定义简单的类, 不包含属性, 在 python 中定义类需要使用关键字 class

      方法: 方法的本质是在类中定义的函数, 只不过,第一个参数是 self
    class 类名:
        # 在缩进中书写的内容,都是类中的代码
        def 方法名(self):   # 就是一个方法
            pass 
    
    • 1
    • 2
    • 3
    • 4
    1. 创建对象
      创建对象是使用 类名() 进行创建,即
    类名()  # 创建一个对象, 这个对象在后续不能使用
    # 创建的对象想要在后续的代码中继续使用, 需要使用一个变量,将这个对象保存起来
    变量 = 类名()  # 这个变量中保存的是对象的地址, 一般可以成为这个变量为对象# 一个类可以创建多个对象, 只要出现 类名() 就是创建一个对象,每个对象的地址是不一样的
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 调用方法
    对象.方法名()
    ​
    列表.sort()
    列表.append()
    
    • 1
    • 2
    • 3
    • 4
    1. 案例实现
    需求:小猫爱吃鱼,小猫要喝水
    类名: 猫类 Cat
    属性: 暂无
    方法: 吃鱼 (eat)  喝水 (drink )
    
    • 1
    • 2
    • 3
    • 4
    """
    需求:小猫爱吃鱼,小猫要喝水, 定义不带属性的类
    """
    ​
    ​
    class Cat:
        # 在缩进中书写 方法
        def eat(self):  # self 会自动出现,暂不管
            print('小猫爱吃鱼...')def drink(self):
            print('小猫要喝水----')
    ​
    ​
    # 2. 创建对象
    blue_cat = Cat()
    # 3. 通过对象调用类中的方法
    blue_cat.eat()
    blue_cat.drink()# 创建对象
    black_cat = Cat()
    black_cat.eat()
    black_cat.drink()
    ​
    Cat()  # 是
    ​
    a = black_cat  # 不是
    b = Cat   # 不是
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    self 的说明

    class Cat:
        # 在缩进中书写 方法
        def eat(self):  # self 会自动出现,暂不管
            print('小猫爱吃鱼...')
    ​
    black_cat.eat()
    1. 从函数的语法上讲, self是形参, 就可以是任意的变量名, 只不过我们习惯性将这个形参写作 self
    2. self 是普通的形参, 但是在调用的时候没有传递实参值,  原因是, Python 解释器在执行代码的时候, 自动的将调用这个方法的对象 传递给了 self, 即 self 的本质是对象
    ​
    3. 验证, 只需要确定 通过哪个对象调用, 对象的引用和 self 的引用是一样的
    ​
    4. self 是函数中的局部变量, 直接创建的对象是全局变量
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    """
    需求:小猫爱吃鱼,小猫要喝水, 定义不带属性的类
    """
    ​
    ​
    class Cat:
        # 在缩进中书写 方法
        def eat(self):  # self 会自动出现,暂不管
            print(f'{id(self)}, self')
            print('小猫爱吃鱼...')
    ​
    ​
    # 2. 创建对象
    blue_cat = Cat()
    print(f'{id(blue_cat)}, blue_cat')
    # 3. 通过对象调用类中的方法
    blue_cat.eat()  # blue_cat 对象调用 eat 方法, 解释器就会将 blue_cat 对象传给 self
    print('_*_' * 30)
    # 创建对象
    black_cat = Cat()
    print(f"{id(black_cat)}, black_cat")
    black_cat.eat()  # black_cat 对象调用 eat 方法, 解释器就会将 black_cat 对象传给 self
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    对象的属性操作

    添加属性

    对象.属性名 = 属性值

    • 类内部添加
    在内部方法中, self 是对象,
    self.属性名 = 属性值
    # 在类中添加属性一般写在 __init__ 方法中
    
    • 1
    • 2
    • 3
    • 类外部添加
    对象.属性名 = 属性值  # 一般不使用
    
    • 1

    获取属性

    对象.属性名

    • 类内部

    在内部方法中, self 是对象,
    self.属性名

    • 类外部

    对象.属性名 # 一般很少使用

    class Cat:
        # 在缩进中书写 方法
        def eat(self):  # self 会自动出现,暂不管
            print(f'{id(self)}, self')
            print(f'小猫{self.name} 爱吃鱼...')
    ​
    ​
    # 2. 创建对象
    blue_cat = Cat()
    print(f'{id(blue_cat)}, blue_cat')
    # 给 蓝猫添加 name 属性
    blue_cat.name = '蓝猫'
    # 3. 通过对象调用类中的方法
    blue_cat.eat()  # blue_cat 对象调用 eat 方法, 解释器就会将 blue_cat 对象传给 self
    print('_*_' * 30)
    # # 创建对象
    black_cat = Cat()
    black_cat.name = '黑猫'
    print(f"{id(black_cat)}, black_cat")
    black_cat.eat()  # black_cat 对象调用 eat 方法, 解释器就会将 black_cat 对象传给 self
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    魔法方法

    python 中有一类方法, 以两个下划线开头,两个下划线结尾,并且在满足某个条件的情况下, 会自动调用, 这类方法称为 魔法方法

    学习:

    1. 什么情况下自动调用
    2. 有什么用, 用在哪
    3. 书写的注意事项

    init 方法 **

    1. 什么情况下自动调用

      创建对象之后会自动调用

    2. 有什么用, 用在哪
      1. 给对象添加属性的, (初始化方法, 构造方法) 2. 某些代码, 在每次创建对象之后, 都要执行,就可以将这行代码写在 init 方法
    3. 书写的注意事项
      1. 不要写错了 2. 如果 init 方法中,存在出了 self 之外的参数, 在创建对象的时候必须传参
    """
    猫类, 属性 name, age , show_info(输出属性信息)
    """
    ​
    ​
    class Cat:
        # 定义添加属性的方法
        def __init__(self, name, age):  # 这个方法是创建对象之后调用
            self.name = name  # 给对象添加 name 属性
            self.age = age   # 给对象添加 age 属性# 输出属性信息
        def show_info(self):
            print(f'小猫的名字是: {self.name}, 年龄是: {self.age}')
    ​
    ​
    # 创建对象,不要在自己类缩进中创建
    # Cat()  # 创建对象 ,会输出
    blue_cat = Cat('蓝猫', 2)
    ​
    blue = blue_cat
    blue.show_info()# 创建黑猫
    black_cat = Cat('黑猫', 3)
    black_cat.show_info()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    str 方法 *

    1. 什么情况下自动调用

      使用 print(对象) 打印对象的时候 会自动调用

    2. 有什么用, 用在哪

      在这个方法中一般书写对象的 属性信息的, 即打印对象的时候想要查看什么信息,在这个方法中进行定义的
      如果类中没有定义 str 方法, print(对象) ,默认输出对象的引用地址

    3. 书写的注意事项

      这个方法必须返回 一个字符串

    class Cat:
        # 定义添加属性的方法
        def __init__(self, n, age):  # 这个方法是创建对象之后调用
            self.name = n  # 给对象添加 name 属性
            self.age = age   # 给对象添加 age 属性def __str__(self):
            # 方法必须返回一个字符串, 只要是字符串就行,
            return f'小猫的名字是: {self.name}, 年龄是: {self.age}'
    ​
    ​
    # 创建对象,不要在自己类缩进中创建
    # Cat()  # 创建对象 ,会输出
    blue_cat = Cat('蓝猫', 2)
    print(blue_cat)# 创建黑猫
    black_cat = Cat('黑猫', 3)
    print(black_cat)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    del 方法 [了解]

    init 方法, 创建对象之后,会自动调用 (构造方法)
    del 方法, 对象被删除销毁时, 自动调用的(遗言, 处理后事) (析构方法)

    1. 调用场景, 程序代码运行结束, 所有对象都被销毁
    2. 调用场景, 直接使用 del 删除对象(如果对象有多个名字(多个对象引用一个对象),需要吧所有的对象都删除才行 )
    class Demo:
        def __init__(self, name):
            print('我是 __init__, 我被调用了 ')
            self.name = name
    ​
        def __del__(self):
            print(f'{self.name} 没了, 给他处理后事...')
    ​
    ​
    # Demo('a')
    ​
    a = Demo('a')
    ​
    b = Demo('b')
    del a  # 删除销毁 对象,
    print('代码运行结束')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    复习:

    魔法方法:

    1. 方法什么时候自动调用, 调用时机
    2. 方法做什么用, 用在哪
    3. 注意事项

    init 初始化方法,

    1. 创建对象后
    2. 给对象添加属性的
    3. 不要写错, 如果存在 self 之外的形参,创建对象时,需要传递实参

      str 方法
    4. print(对象) 会自动调用
    5. 想要打印输出对象的时候, 输出对象的属性信息
    6. 必须返回一个字符串

      dir(对象) 获取对象所有的方法

    作业一

    类名: 学生类 Student
    属性: 姓名 name, 年龄 age
    方法: 吃饭 eat 睡觉 sleep 过年year , str , init

    class Student:
        # 添加属性
        def __init__(self, name, age):
            self.name = name
            self.age = age
    ​
        def __str__(self):
            return f"姓名: {self.name}, 年龄: {self.age} 岁"def eat(self):
            print(f'{self.name} 要吃饭')def sleep(self):
            print(f'{self.name} 要睡觉')def year(self):
            self.age += 1
    ​
    ​
    # 创建对象
    xm = Student('小明', 18)
    xh = Student('小红', 17)
    print(xm)
    print(xh)
    xm.eat()
    xm.sleep()
    xm.year()
    print(xm)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    作业二

    类名: 电脑类 Computer
    属性: 品牌 brand , 价格 price [movie 电影的名字]
    方法: play_movie

    class Computer:
        def __init__(self, brand, price):
            self.brand = brand
            self.price = price
    ​
        def play_movie(self, movie):
            print(f'{self.brand} 播放电影 {movie}')
    ​
    ​
    # 创建对象
    mi = Computer('小米', 4999)
    mac = Computer('Mac', 16999)
    mi.play_movie('葫芦娃')
    mac.play_movie('变形金刚')
    mi.play_movie('西游记')
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    封装

    案例一

    在这里插入图片描述

    # 定义家具类
    class HouseItem:
        """家具类"""
        def __init__(self, name, area):
            """添加属性的方法"""
            self.name = name
            self.area = area
    ​
        def __str__(self):
            return f'家具名字{self.name}, 占地面积 {self.area} 平米'
    ​
    ​
    class House:
        """房子类"""
        def __init__(self, name, area):
            self.name = name  # 户型
            self.total_area = area  # 总面积
            self.free_area = area   # 剩余面积
            self.item_list = []     # 家具名称列表def __str__(self):
            return f"户型: {self.name}, 总面积:{self.total_area}平米, 剩余面积: {self.free_area} 平米, " \
                   f"家具名称列表: {self.item_list}"def add_item(self, item):  # item  表示的家具的对象
            # 判断房子的剩余面积(self.free_area)和家具的占地面积(item.area)之间的关系
            # self 表示的 房子对象, 缺少一个家具对象使用传参解决
            if self.free_area > item.area:
                # 添加家具, ---> 向列表中添加数据
                self.item_list.append(item.name)
                # 修改剩余面积
                self.free_area -= item.area
                print(f'{item.name} 添加成功')
            else:
                print('剩余面积不足, 换个大房子吧')
    ​
    ​
    # 创建家具对象
    bed = HouseItem('席梦思', 4)
    chest = HouseItem('衣柜', 2)
    table = HouseItem('餐桌', 1.5)
    print(bed)
    print(chest)
    print(table)# 创建房子对象
    house = House('三室一厅', 150)
    print(house)
    # 添加 床
    house.add_item(bed)
    print(house)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    案例二

    在这里插入图片描述

    class LoginPage:
        def __init__(self, username, password, code):
            self.username = username
            self.password = password
            self.code = code
            self.btn = '登录'def login(self):
            print(f'1. 输入用户名 {self.username}')
            print(f'2. 输入密码 {self.password}')
            print(f'3. 输入验证码 {self.code}')
            print(f"4. 点击按钮 {self.btn}")
    ​
    ​
    login = LoginPage('admin', '123456', '8888')
    login.login()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    私有和公有

    在这里插入图片描述

    • 案例

    定义一个 Person 类, 属性 name, age(私有)

    • 代码
    class Person:
        def __init__(self, name, age):
            self.name = name   # 姓名
            # 私有的本质, 是 Python 解释器执行代码,发现属性名或者方法名前有两个_, 会将这个名字重命名
            # 会在这个名字的前边加上 _类名前缀,即 self.__age ===> self._Person__age
            self.__age = age  # 年龄, 将其定义为私有属性, 属性名前加上两个 _def __str__(self):  # 在类内部可以访问私有属性的
            return f'名字: {self.name}, 年龄: {self.__age}'
    ​
    ​
    xm = Person('小明', 18)
    print(xm)
    # 在类外部直接访问 age 属性
    # print(xm.__age)  # 会报错, 在类外部不能直接使用私有属性
    # 直接修改 age 属性
    xm.__age = 20  # 这个不是修改私有属性, 是添加了一个公有的属性 __age
    print(xm)  # 名字: 小明, 年龄: 18
    print(xm._Person__age)  # 能用但是不要用  18
    xm._Person__age = 19
    print(xm)  # 名字: 小明, 年龄: 19
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    继承

    1. 继承描述的是类与类之间的关系
    2. 继承的好处: 减少代码的冗余(相同的代码不需要多次重复书写), 可以直接使用

    语法

    # class A(object):
    class A: # 没有写父类,但也有父类, object, object 类是 Python 中最顶级(原始)的类
        pass
    ​
    class  B(A):  # 类 B, 继承类 A
        pass 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    • 案例
    1. 定义一个 动物类, 吃
    2. 定义一个 狗类, 继承动物类, 吃, 叫
    3. 定义一个 哮天犬类, 继承 狗类
    • 代码
    # 1. 定义一个 动物类, 吃
    class Animal:
        def eat(self):
            print('要吃东西')# 2. 定义一个 狗类, 继承动物类, 吃, 叫
    class Dog(Animal):
        def bark(self):
            print('汪汪汪叫....')# 3. 定义一个 哮天犬类, 继承 狗类
    class XTQ(Dog):
        pass# 创建 动物类的对象
    # ani = Animal()
    # ani.eat()
    # 创建狗类对象
    # dog = Dog()
    # dog.eat()  # 调用父类中的方法
    # dog.bark()   # 调用自己类中方法
    # 创建哮天犬类对象
    xtq = XTQ()
    xtq.bark()  # 调用 父类 Dog 类的方法
    xtq.eat()   # 可以调用 父类的父类中的方法
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 结论

    python 中 对象.方法() 调用方法

    1. 现在自己的类中的去找有没有这个方法 如果有,直接调用
    2. 如果没有去父类中 查找, 如果有,直接调用
    3. 如果没有, 去父类的父类中查找, 如果有直接调用
    4. 如果 object 类中有,直接调用, 如果没有,代码报错

    重写

    重写: 在子类中定义了和父类中名字相同的方法, 就是重写
    重写的原因: 父类中的方法,不能满足子类对象的需求,所以重写
    重写之后的特点: 调用子类字节的方法, 不再调用父类中的方法
    重写的方式:
    >1. 覆盖(父类中功能完全抛弃,不要,重写书写)
    >2. 扩展(父类中功能还调用,只是添加一些新的功能) (使用较多)

    覆盖

    1. 直接在子类中 定义和父类中名字相同的方法
    2. 直接在方法中书写新的代码
    class Dog:
        def bark(self):
            print('汪汪汪叫.....')
    ​
    ​
    class XTQ(Dog):
        # XTQ 类bark 方法不再是汪汪汪叫, 改为 嗷嗷嗷叫
        def bark(self):
            print('嗷嗷嗷叫...')
    ​
    ​
    xtq = XTQ()
    xtq.bark()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    扩展父类中的功能

    1. 直接在子类中 定义和父类中名字相同的方法
    2. 在合适的地方调用 父类中方法 super().方法()
    3. 书写添加的新功能
    class Dog:
        def bark(self):
            print('汪汪汪叫.....')
            print('汪汪汪叫.....')
            
    class XTQ(Dog):
        # XTQ 类bark 方法不再是汪汪汪叫, 改为
        # 1. 先 嗷嗷嗷叫(新功能) 2, 汪汪汪叫(父类中功能)  3. 嗷嗷嗷叫 (新功能)
        def bark(self):
            print('嗷嗷嗷叫...')
            # 调用父类中的代码
            super().bark()  # print() 如果父类中代码有多行呢?
            print('嗷嗷嗷叫...')
    ​
    xtq = XTQ()
    xtq.bark()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    多态[了解]

    1. 是一种写代码,调用的一种技巧
    2. 同一个方法, 传入不同的对象, 执行得到不同的结果, 这种现象称为是多态
    3. 多态 可以 增加代码的灵活度

    哪个对象调用方法, 就去自己的类中去查找这个方法, 找不到去父类中找

    属性和方法

    Python 中一切皆对象.
    即 使用 class 定义的类 也是一个对象

    对象的划分

    实例对象(实例)

    1. 通过 类名() 创建的对象, 我们称为实例对象,简称实例
    2. 创建对象的过程称为是类的实例化
    3. 我们平时所说的对象就是指 实例对象(实例)
    4. 每个实例对象, 都有自己的内存空间, 在自己的内存空间中保存自己的属性(实例属性)

    类对象(类)

    1. 类对象 就是 类, 或者可以认为是 类名
    2. 类对象是 Python 解释器在执行代码的过程中 创建的
    3. 类对象的作用: ① 使用类对象创建实例 类名(), ② 类对象 也有自己的内存空间, 可以保存一些属性值信息 (类属性)
    4. 在一个代码中, 一个类 只有一份内存空间

    属性的划分

    实例属性

    • 概念: 是实例对象 具有的属性
    • 定义和使用
      在 init 方法中, 使用 self.属性名 = 属性值 定义
      在方法中是 使用 self.属性名 来获取(调用)
    • 内存
      实例属性,在每个实例中 都存在一份
    • 使用时机
    1. 基本上 99% 都是实例属性,即通过 self 去定义
    2. 找多个对象,来判断这个值是不是都是一样的, 如果都是一样的, 同时变化,则一般定义为 类属性, 否则定义为 实例属性

    类属性

    • 概念: 是 类对象 具有的属性
    • 定义和使用
      在类内部,方法外部,直接定义的变量 ,就是类属性

      使用: 类对象.属性名 = 属性值 or 类名.属性名 = 属性值
      类对象.属性名 or 类名.属性名
    • 内存

    只有 类对象 中存在一份

    方法的划分

    方法, 使用 def 关键字定义在类中的函数就是方法

    实例方法(最常用)

    • 定义
    # 在类中直接定义的方法 就是 实例方法
    class Demo:
        def func(self):   # 参数一般写作 self,表示的是实例对象
            pass
    
    • 1
    • 2
    • 3
    • 4
    • 定义时机(什么时候用)

    如果在方法中需要使用实例属性(即需要使用 self), 则这个方法必须定义为 实例方法

    • 调用

    对象.方法名() # 不需要给 self 传参

    类方法(会用)

    • 定义
    # 在方法名字的上方书写 @classmethod 装饰器(使用 @classmethod 装饰的方法)
    class Demo:
        @classmethod
        def func(cls):  # 参数一般写作 cls, 表示的是类对象(即类名) class
            pass 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 定义时机(什么时候用)
    1. 前提, 方法中不需要使用 实例属性(即 self)
    2. 用到了类属性, 可以将这个方法定义为类方法,(也可以定义为实例方法)
    • 调用
    # 1. 通过类对象调用
    类名.方法名()  # 也不需要给 cls 传参, python 解释器自动传递
    # 2. 通过实例对象调用
    实例.方法名()  # 也不需要给 cls 传参, python 解释器自动传递
    
    • 1
    • 2
    • 3
    • 4

    静态方法(基本不用)

    • 定义
    # 在方法名字的上方书写 @staticmethod 装饰器(使用 @staticmethod 装饰的方法)
    class Demo:
        @staticmethod
        def func():   # 一般没有参数
            pass 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 定义时机(什么时候用)
    1. 前提, 方法中不需要使用 实例属性(即 self)
    2. 也不使用 类属性, 可以将这个方法定义为 静态方法
      在这里插入图片描述
    • 调用
    # 1. 通过类对象调用
    类名.方法名() 
    # 2. 通过实例对象调用
    实例.方法名()  
    
    • 1
    • 2
    • 3
    • 4

    练习

    练习 1

    定义一个 Dog 类, 定义一个类属性 count,用来记录创建该类对象的个数. (即每创建一个对象,count 的值就要加1)实例属性 name

    class Dog:
        # 定义类属性
        count = 0# 定义实例属性, init 方法中
        def __init__(self, name):
            self.name = name   # 实例属性
            # 因为每创建一个对象,就会调用 init 方法, 就将个数加 1 的操作,写在 init 方法中
            Dog.count += 1
    ​
    ​
    # 在类外部
    # 打印输出目前创建几个对象
    print(Dog.count)  # 0
    # 创建一个对象
    dog1 = Dog('小花')
    # 打印输出目前创建几个对象
    print(Dog.count)  # 1
    dog2 = Dog   # 不是创建对象, 个数不变的
    dog3 = dog1  # 不是创建对象, 个数不变的
    print(Dog.count)  # 1
    ​
    dog4 = Dog('大黄')  # 创建一个对象 , 个数 + 1
    print(Dog.count)  # 2
    dog5 = Dog('小白')
    print(Dog.count)  # 3# 补充, 可以使用 实例对象.类属性名 来获取类属性的值  (原因, 实例对象属性的查找顺序, 先在实例属性中找,找到直接使用
    # 没有找到会去类属性中 找, 找到了可以使用, 没有找到 报错)
    print(dog1.count)  # 3
    print(dog4.count)  # 3
    print(dog5.count)  # 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    练习 2

    在这里插入图片描述
    主程序步骤

    # 1) 创建一个 Game 对象  小王
    # 2) 小王玩一次游戏,
    # 3) 查看历史最高分
    # 4) 小王再玩一次游戏
    # 5) 查看历史最高分
    # 6) 查看游戏的帮助信息
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 基本版本
    import random
    ​
    class Game:
        # 类属性, 游戏的最高分
        top_score = 0def __init__(self, name):
            # 定义实例属性 name
            self.name = name
    ​
        def show_help(self):
            print('这是游戏的帮助信息')def show_top_score(self):
            print(f'游戏的最高分为 {Game.top_score}')def start_game(self):
            print(f'{self.name} 开始一局游戏, 游戏中 ...,', end='')
            score = random.randint(10, 100)  # 本次游戏的得分
            print(f'本次游戏得分为 {score}')
            if score > Game.top_score:
                # 修改最高分
                Game.top_score = score
    ​
    xw = Game('小王')
    xw.start_game()
    xw.show_top_score()
    xw.start_game()
    xw.show_top_score()
    xw.show_help()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 优化 (使用 类方法和静态方法)
       @staticmethod
        def show_help():
            print('这是游戏的帮助信息')@classmethod
        def show_top_score(cls):
            print(f'游戏的最高分为 {cls.top_score}')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    要想组建敏捷团队,这些方法不可少
    C#基于ScottPlot进行可视化
    SQL慢?吐血整理MySQL中Explain分析工具
    N 皇后问题
    android adb工具命令大全
    容器K8s(Kubernetes)教程
    Spring Boot 学习总结(31)—— Spring Native 主要知识点总结
    Java基本数据类型和变量
    Visual Studio Code配置Tomcat运行Java Web项目
    【计算机网络仿真实验-实验2.6】带交换机的RIP路由协议
  • 原文地址:https://blog.csdn.net/weixin_45990326/article/details/125460002