• 面向对象基础


    编程思想

    编程思想 - 程序员在遇到问题解决问题的思维模式

    1.面向过程编程 -基本语法,逻辑

    2.函数式编程 - 掌握函数 (遇到问题先想想有没有一个已经存在的函数具备解决这个问题的能力,如果有直接调用。没有就创建一个这样的函数)

    3.面向对象过程 - 类、对象(变量、函数)

    python只是一个工具,函数只是机器,遇到问题首先寻找有没有能解决问题的机器,没有就自己创造。如果能创造一个能解决所有问题的机器,是最理想状态。程序员应该往这方面去思考。

    类和对象

    1.类就是拥有相同功能和相同属性的对象的集合 - 抽象的概念
    对象就是类的实例(类具体的表现)

    人是类,具体的一个人就是它的对象,比如:亚索,瑞文
    电脑是类,具体的电脑就是它的对象,比如:我桌上的电脑
    杯子是类,我桌上的所有杯子都是它的对象
    list是类,[10,20]是列表的对象

    类不能直接使用,因为没有听说过我要人去干某一件事情,只会说叫某个人去干某件事情,即不能叫英雄去打中路,只有叫亚索(类的实例)去打中路的说法。 类就是英雄,亚索就是对象(类的实例)。

    2.定义类(创建类) - 用代码描述清楚这个类是拥有哪些相同功能和哪些相同属性的对象的集合

    功能 - 函数

    属性 - 保存数据的变量

    语法:

    class 类名:
    类的说明文档
    类的内容

    说明:

    1)class - 关键字;固定写法
    2)类名 - 程序员自己命名
    都是采用驼峰式命名,首字母大写(类名大写字母开头;驼峰式 - 从第二个单词开始首字母大写)
    3): - 固定写法
    4)类的说明问题 -多行注释
    5)类的内容 - 相同的功能和相同的属性
    由方法(对象方法、类方法、静态方法)和属性(对象属性、类属性)组成
    方法 - 定义在类中的函数
    属性 - 定义在类中的变量

    class Person:
        '''人的类'''
        num = 61  # 类属性
    
        def eat(self):  # 方法
            print('吃饭')
    
        def sleep(self):  # 方法
            print('睡')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    类的内容肯定没有这么简单,为了进一步学习才会使用简单的例子体验一下创建类的样子

    3.创建对象
    语法:

    类名() - 创建指定类对应的一个对象,并且将对象返回

    p1 = Person()     
    p2 = Person()
    print(p1, p2)
    
    • 1
    • 2
    • 3

    p1,p2 都是类的对象 ,此时p1和p2就是类的实例。就好比人这个类中,创建了2个实例的人出来。

    类中的方法

    1.方法 - 定义在类中的函数,用来描述类具备的功能

    类中的方法有3种:对象方法、类方法、静态方法

    1)对象方法

    a.怎么定义:将函数直接定义在类中
    b.怎么调用:通过对象来调用 - 对象.xxx()
    c.特点:自带参数self,通过对象调用对象方法的时候参数self不需要传参,系统会自动将当前对象传给self
    (self,谁调用就指向谁)
    d.什么时候用:如果实现函数的功能需要用到对象属性就使用对象方法

    2)类方法

    a.怎么定义:定义函数前加装饰器’@classmethod’
    b.怎么调用:通过类来调用 - 类名.xxx()
    c.特点:自带参数cls,调用的时候不需要传参,系统自动将当前类传给cls
    d.什么时候用:如果实现函数的功能不需要对象属性需要类就是用类方法

    3)静态方法

    a.怎么定义:定义函数前加装饰器’@staticmethod’
    b.怎么调用:通过类来调用 - 类名.xxx()
    c.特点:没有特点
    d.什么时候用:实现函数功能既不需要对象属性也不需要类

    class A:
        def func1(self):
            print(f'self:{self}')
            print('对象方法')
    
        def func11(self, x, y):
            print('对象方法2')
    
        @classmethod
        def func2(cls):
            print(cls)
            print('类方法')
    
        @staticmethod
        def func3():
            print('静态方法')
    
    
    print(A)
    a = A()
    # 通过对象调用对象方法
    a.func1()
    a.func11(11, 20)
    
    # 通过类调用类的方法
    A.func2()
    # 通过类调用静态方法
    A.func3()
    # 上述中有参数的函数没有传参,系统自动给self和cls传一个参数,这个参数就是a对象,
    
    • 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

    常用的魔法方法

    方法名以__开头并且以__结尾的自带的方法
    所有的魔法方法都会在特定的情况下自动调用。

    常用的魔法方法:__init__方法、__repr__方法

    1)repr - 打印对象的时候会自动调用对象对应的类中的__repr__方法,用来制定打印规则(函数的返回值是什么,对象打印结果就是什么)

    返回值必须是字符串

    class A:
        def __repr__(self):
            return 'as'
    
    
    a = A()
    print(a)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    2)init - 每次创建类的对象的时候会自动调用类中的__init__方法
    class B:
        def __init__(self):
            print('init方法')
    
        def pa(self):
            print('pa')
    
    
    b1 = B()
    b1.pa()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    class C:
        # 在类中添加__init__方法的时候,除了方法名和方法类型不能动,可以随意添加参数和随意添加函数体
        def __init__(self, x, y):
            print('C的init方法')
    
    
    # c1 = C()   会报错 因为 创造类的对象的时候会自动调用__init__方法,里面有2个参数
    # 创建类的对象的时候需不需要参数,需要几个参数,由类中__init__方法决定
    c1 = C(10, 20)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    属性

    1.属性:分为对象属性和类属性两种
    1)类属性

    a.怎么创建:在类中之间定义一个变量,这个变量就是类属性
    b.怎么使用:通过类来使用 - 类.xxx
    c.什么时候用 :当属性值不会因为对象不同而不一样的时候就使用类属性

    2)对象属性

    a.怎么创建:以’self.属性名 = 值’的形式定义在类的__init__方法
    b.怎么使用:通过对象来使用 -对象.属性名
    c.什么时候用:当属性值会因为对象不同而不一样的时候就使用类属性

    class A:
        x = 100  # 类属性
    
        # name 和num是对象属性
        def __init__(self):
            self.name = '小明'
            self.num = 10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    属性的使用方法
    # 使用类属性
    print(A.x)
    # 修改类属性的值
    A.x = 200
    print(A.x)
    
    a = A()
    print(a.name, a.num)
    # 修改对象属性的值
    a.name = '小红'
    a.num = 18
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    2.对象属性赋初始值的方式
    class Person:
        def __init__(self, name, gender='男'):
            self.name = name  # 使用没有默认值的参数来赋值
            self.age = 1  # 赋固定值
            self.gender = gender  # 使用有默认值的参数来赋值
        def __repr__(self):
            return str(self.__dict__)   #"{'name': '小明', 'age': 1, 'gender': '男'}"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    p1 = Person('小明')
    print(p1)
    print(p1.name, p1.age, p1.gender)
    p2 = Person('小花', '女')
    print(p2.name, p2.age, p2.gender)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    属性的增删改

    1.面向对象编程的时候,可以直接使用对象来代替字典
    stu = {'name': '小明', 'age': 18, 'score': 67}
    
    
    class Student:
        def __init__(self, name, age=18, score=0):
            self.name = name
            self.age = age
            self.score = score
    
        def __repr__(self):
            return str(self.__dict__)
    
    
    stu1 = Student('小明', 12, 68)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    虽然开始会很复杂,没有字典的好用,但是这个过程创建完了之后,所有的数据传进去都会很轻松
    2.对象的对象属性也支持增删改查

    1)查 - 获取属性值

    a. 对象.属性 - 获取指定属性对应的值

    b. getattr(对象,属性名) - 获取指定属性的值

    c.getattr(对象,属性名,默认值) - 获取指定属性的值,属性不存在直接返回默认值

    print(stu1.name)
    print(getattr(stu1, 'name'))
    
    # print(stu1.gender)     报错
    # print(getattr(stu1, 'gender'))    报错
    print(getattr(stu1, 'gender', '男'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2)增、改

    a.对象.属性 = 值 - 当属性存在时修改指定属性的值,当属性不存在的时候添加属性的值

    b.setattr(对象,属性名,值) - 当属性存在的时候修改对应的值,当属性不存在的时候添加属性

    print(stu1)  # {'name': '小明', 'age': 12, 'score': 68}
    
    stu1.age = 22  # {'name': '小明', 'age': 22, 'score': 68}
    print(stu1)
    
    stu1.gender = '男'  # {'name': '小明', 'age': 22, 'score': 68, 'gender': '男'}
    print(stu1)
    
    setattr(stu1, 'id', '001')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    # attr相关函数可以动态操作对象属性
    value = input('请输入你想要查看的属性:')
    print(stu1.value)     
    print(getattr(stu1, value))
    
    • 1
    • 2
    • 3
    • 4

    3)删

    del 对象.属性

    delattr(对象,属性名)

    print(stu1)  # {'name': '小明', 'age': 22, 'score': 68, 'gender': '男', 'id': '001'}
    del stu1.age
    print(stu1)
    delattr(stu1, 'name')
    print(stu1)
    # 上述都不能删除不存在的属性
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4)判断对象是否存在

    hasattr(对象,属性名)

    print(hasattr(stu1, 'name'))  # False
    print(hasattr(stu1, 'score'))   #True
    
    if not hasattr(stu1, 'name'):
        stu1.name = '小明'   # 判断属性实在在其中,没有就添加
    
    • 1
    • 2
    • 3
    • 4
    • 5

    对象.__dict__方法查看

    print('score' in stu1.__dict__)
    
    • 1

    继承

    1.继承 - 让字类直接用拥有父类的属性和方法

    父类就是一个大的类,子类就是这个大的类下面的一个小的分类

    2.继承的语法

    class 类名(父类):
    类的说明文档
    类的内容

    注意:定义类的时候如果没有写父亲,这个类默认继承object(基类)
    # class Person:  == class  Person(object):
    
    • 1
    class A:
        a = 100
    
        def __init__(self, w, d, a):
            self.b = 10
            self.c = 20
    
        def func1(self):
            print('对象方法')
    
        @classmethod
        def func2(cls):
            print('类方法')
    
        @staticmethod
        def func3():
            print('静态方法')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    class B(A):
        pass
    
    
    x = B(1,2,3)
    print(B.a)
    print(x.b, x.c)
    x.func1()
    x.func2()
    x.func3()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    3.子类添加内容

    子类在拥有父类的属性和方法的同时,往往需要有属性自己特有的一些属性和方法

    1)添加类属性和方法
    直接在子类中定义新的类属性和新的方法

    2)添加对象属性

    class C(A):
        m = 11
    
        def __init__(self):
            super().__init__(1, 2, 5)  # 调用当前类的父类的__init__()
            self.name = '小明'  # 加了之后父类的就用不了了,因为重名 必须添加super().__init__()
    
        def func11(self):
            print('Cde对象方法')
    
        @classmethod
        def func22(cls):
            print('Cde类方法')
    
        @staticmethod
        def func33():
            print('Cde静态方法')
    
        def func1(self):
            print('Cde对象方法')  # 重名会覆盖父类的方法
    
    
    
    x = C()
    print(x.name, x.b)
    
    • 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

    练习:

    #创建圆类,里面有周长和面积的方法
    class Round:
        pai = 3.14
    
        def __init__(self, r):
            self.ban = r
    
        def zc(self):
            # self = c1
            # 如果需要类属性直接用类来提供
            # 如果需要对象属性用self来提供
            return 2 * Round.pai * self.ban
    
        def mj(self):
            return self.pai * self.ban ** 2
    
    
    r = Round(4)
    print(r.zc())
    print(r.mj())
    print('---------------------------------华丽的分割线---------------------------------')
    #创建一个矩形类
    class Rectangle:
        def __init__(self,length,width):
            self.l = length
            self.w = width
        def get_Perimeter(self):
            return (self.l + self.w) *2
        def get_area(self):
            return self.l * self.w
        def __repr__(self):
            return str(self.__dict__)[1:-1]
    
    a1 = Rectangle(5,8)
    print(a1)
    print(a1.get_Perimeter(),a1.get_area())
    print('---------------------------------华丽的分割线---------------------------------')
    
    class Student:
        def __init__(self, name, age=18, score=0):
            self.name = name
            self.age = age
            self.score = score
        # def __repr__(self):
        #     return str(self.__dict__)
    s = Student(1)
    dic = s.__dict__
    print(dic)
    print('name' in dic)
    
    • 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
  • 相关阅读:
    LAS、CTC、RNN-T、NT、MoChA
    556. 下一个更大元素 III
    HIVE/SQL 实现同一列数据累加和累乘
    flink重温笔记(九):Flink 高级 API 开发——flink 四大基石之WaterMark(Time为核心)
    分布式锁
    ArduinoUNO实战-第五章-有源蜂鸣器实验
    使用Java实现汉诺塔问题~
    【Docker项目实战】使用Docker部署HFish蜜罐系统
    2023年的当下,应该学习Python哪个版本?哪个方向好?
    【华为游戏服务】同一游戏同一个手机号的华为帐号登录返回的playerId不同
  • 原文地址:https://blog.csdn.net/ZiXiaoAo/article/details/126170634