• Python3 面向对象,一篇就够了


    1.类定义

    语法格式如下:

    class ClassName:
        <statement-1>
        .
        .
        .
        <statement-N>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性。


    2.类对象

    类对象支持两种操作:属性引用和实例化。

    属性引用使用和 Python 中所有的属性引用一样的标准语法:obj.name

    类对象创建后,类命名空间中所有的命名都是有效属性名。所以如果类定义是这样:

    class Myclass:
        i = 123
    
        def f(self):
            return 'hello world'
    
    # 实例化类
    x = Myclass()
    
    # 访问类的属性和方法
    print(x.i)  # 123
    print(x.f())  # hello world
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    类有一个名为 __init__() 的特殊方法(构造方法),该方法在类实例化时会自动调用

    如下实例化类 MyClass,对应的 __init__() 方法就会被调用:

    class Myclass:
        i = 123
    
        def __init__(self):
            print("我是类的构造方法!")
    
        def f(self):
            return 'hello world'
    
    # 实例化类
    x = Myclass()
    
    # 访问类的属性和方法
    # 我是类的构造方法!
    print(x.i)  # 123
    print(x.f())  # hello world
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    当然, __init__() 方法可以有参数,参数通过 __init__() 传递到类的实例化操作上,相当于java中的有参构造

    self代表类的实例,而非类🏀

    类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self

    class Test:
        def prt(self):
            print(self)
            print(self.__class__)
    
    
    t = Test()  # <__main__.Test object at 0x00000213E6693730>
    t.prt()  # 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    从执行结果可以很明显的看出,self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类🏐


    3.类的方法

    在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例

    以下是一个常见类的示例:

    class People:
        # 定义基本属性
        name = ''
        age = 0
        # 定义私有属性
        __weight = 0
    
        # 构造方法
        def __init__(self, n, a, w):
            self.name = n
            self.age = a
            self.__weight = w
    
        # 类中的普通方法
        def speak(self):
            print('{}说,我今年{}岁'.format(self.name, self.age))
    
    
    # 实例化类
    p = People('dahe', 10, 70)
    p.speak()  # dahe说,我今年10岁
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4.继承

    Python 同样支持类的继承,如果一种语言不支持继承,类就没有什么意义。派生类的定义如下所示:

    class DerivedClassName(BaseClassName):
        <statement-1>
        .
        .
        .
        <statement-N>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    子类(派生类 DerivedClassName)会继承父类(基类 BaseClassName)的属性和方法。

    BaseClassName(实例中的基类名)必须与派生类定义在一个作用域内

    单继承

    以下是一个单继承示例:

    class People:
        # 定义基本属性
        name = ''
        age = 0
        # 定义私有属性
        __weight = 0
    
        # 构造方法
        def __init__(self, n, a, w):
            self.name = n
            self.age = a
            self.__weight = w
    
        # 类中的普通方法
        def speak(self):
            print('{}说,我今年{}岁'.format(self.name, self.age))
    
    
    '''
    继承父类的子类
    '''
    class Student(People):
        grade = ''
    
        def __init__(self, n, a, w, g):
            # 调用父类的构造函数
            People.__init__(self, n, a, w)
            self.grade = g
    
        # 覆写父类的方法
        def speak(self):
            print('{}说,我今年{}岁了,我在读{}年级'.format(self.name, self.age, self.grade))
    
    
    s = Student('dahe', 20, 50, 3)
    s.speak()  # dahe说,我今年20岁了,我在读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
    • 33
    • 34
    • 35
    • 36

    多继承

    Python同样有限的支持多继承形式。多继承的类定义形如下例:

    class DerivedClassName(Base1, Base2, Base3):
        <statement-1>
        .
        .
        .
        <statement-N>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法🏈

    慎用多继承❌


    5.方法重写

    如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,这个上面已经演示过了

    super() 函数是用于调用父类(超类)的一个方法。

    super() 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。

    以下是 super() 方法的语法:

    super(type[, object-or-type])
    
    • 1

    参数

    • type – 类。
    • object-or-type – 类,一般是 self

    super()使用示例:

    class A:
         def add(self, x):
             y = x + 1
             print(y)
    class B(A):
        def add(self, x):
            super().add(x)
    b = B()
    b.add(2)  # 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    6.组合

    不到必要的时候不使用多重继承。哎呀,这可让大家烦恼死了,就像我们有了乌龟类、鱼类,现在要求定义一个类,叫水池,水池里要有乌龟和鱼。用多重继承就显得很奇怪,因为水池和乌龟、鱼是不同物种,那要怎样才能把它们组合成一个水池的类呢?

    在Python里其实很简单,直接把需要的类放进去实例化就可以了,这就叫组合:

    class Turtle:
        def __init__(self, x):
            self.num = x
    
    
    class Fish:
        def __init__(self, x):
            self.num = x
    
    
    class Pool:
        def __init__(self, x, y):
            self.turtle = Turtle(x)
            self.fish = Fish(y)
    
        def print_num(self):
            print("水池里面有乌龟 %d 只,鱼儿 %d 只" % (self.turtle.num, self.fish.num))
    
    
    pool = Pool(1, 5)
    pool.print_num()  # 水池里面有乌龟 1 只,鱼儿 5 只
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    7.类和对象相关的一些BIF

    issubclass(class, classinfo)

    如果第一个参数(class)是第二个参数(classinfo)的一个子类,则返回True,否则返回False

    class A:
        pass
    
    
    class B(A):
        pass
    
    
    class C:
        pass
    
    
    print(issubclass(B, A))  # True
    print(issubclass(B, B))  # True
    print(issubclass(B, object))  # True
    print(issubclass(B, C))  # False
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    isinstance(object, classinfo)

    如果第一个参数(object)是第二个参数(classinfo)的实例对象,则返回True,否则返回False

    class A:
        pass
    
    
    class B(A):
        pass
    
    
    class C:
        pass
    
    
    b1 = B()
    print(isinstance(b1, B))  # True
    print(isinstance(b1, C))  # False
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    hasattr(object, name)

    hasattr()函数的作用就是测试一个对象里是否有指定的属性。

    第一个参数(object)是对象,第二个参数(name)是属性名(属性的字符串名字)

    class B:
        pass
    
    b1 = B()
    print(hasattr(b1, 'x'))  # False
    
    • 1
    • 2
    • 3
    • 4
    • 5

    getattr(object, name[, default])

    返回对象指定的属性值,如果指定的属性不存在,则返回default(可选参数)的值;若没有设置default参数,则抛出ArttributeError异常

    class A:
        def __init__(self, x=521):
            self.x = x
    
    
    a = A(1314)
    print(getattr(a, 'x'))  # 1314
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    setattr(object, name, value)

    getattr()对应,setattr()可以设置对象中指定属性的值,如果指定的属性不存在,则会新建属性并赋值

    class A:
        def __init__(self, x=521):
            self.x = x
    
    
    a = A()
    setattr(a, 'x', 1314)
    print(getattr(a, 'x'))  # 1314
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    delattr(object, name)

    setattr()相反,delattr()用于删除对象中指定的属性,如果属性不存在,则抛出AttributeError异常

    class A:
        def __init__(self, x=521):
            self.x = x
    
    
    a = A()
    delattr(a, 'x')
    print(hasattr(a, 'x'))  # False
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    数据结构之时间复杂度&&空间复杂度的计算
    李航《统计学习方法》笔记之朴素贝叶斯法
    ElasticSearch 批量插入漏数据
    PostgreSQL 16 关于vacuum freezing 性能提升的来由 与 之前PostgreSQL 的缺陷讨论
    腾讯云年终选购云服务器攻略!
    学会玩游戏,智能究竟从何而来?
    的修大数据管理平台有哪些功能模块?它可以为企业带来什么好处?
    Python3,我用这种方式讲解python模块,80岁的奶奶都说能理解。建议收藏 ~ ~
    23.1、Android -- OkHttp3请求的数据格式-文件上传
    vue3+ts 项目遇到的问题和bug
  • 原文地址:https://blog.csdn.net/Gherbirthday0916/article/details/126808913