Python类

经典类

不由任意内置类型派生出的类,称之为经典类(存在于Python2.0)。

  1. class 类名:
  2. 代码
  3. ...

新式类

存在于Python3.0以上的类,称之为新式类。

  1. class 类名(object):
  2. 代码
  3. ...
  4. 其中:
  5. object表示的是需要继承的父类,写object或不写参数表示继承的是基类(顶级类)。

面向对象的继承

Python面向对象的继承,指的是多个类之间的所属关系即子类默认继承父类的所有属性和方法

  • 所有类默认继承object类,**object**类是顶级类或基类其他的子类叫作派生类。 ```python

    父类A

    class A(): def init(self):

    1. self.str = "hello world"

    def print_info(self):

    1. print(self.str)

子类B

class B(A): pass

result = B() result.print_info() # hello world

  1. <a name="VEq2N"></a>
  2. ## 单继承
  3. 单继承,指的是**一个类仅继承了一个父类**。
  4. ```python
  5. # 父类A
  6. class A():
  7. def __init__(self):
  8. self.str = "hello world"
  9. def print_info(self):
  10. print(self.str)
  11. # 子类B
  12. class B(A):
  13. pass
  14. result = B()
  15. result.print_info() # hello world

多继承

所谓多继承,指的是一个类同时继承了多个父类

  • 当一个类有多个父类的时候,默认使用的是第一个父类的同名属性和方法。 ```python

    父类A

    class A(object): def init(self):

    1. self.str = "hello world"

    def print_info(self):

    1. print(self.str)

父类B

class B(object): def init(self): self.str = “hi world”

  1. def print_info(self):
  2. print(self.str)

子类C

class C(A, B): pass

result = C() result.print_info() # hello world

  1. <a name="enGhH"></a>
  2. # 子类和父类的方法和属性
  3. <a name="ynTeH"></a>
  4. ## 子类重写父类同名方法和属性
  5. **子类和父类具有同名属性和方法时**,**默认使用子类的同名属性和方法**。
  6. ```python
  7. # 父类A
  8. class A(object):
  9. def __init__(self):
  10. self.str = "hello world"
  11. def print_info(self):
  12. print(self.str)
  13. # 父类B
  14. class B(object):
  15. def __init__(self):
  16. self.str = "hi world"
  17. def print_info(self):
  18. print(self.str)
  19. # 子类C
  20. class C(A, B):
  21. def __init__(self):
  22. self.str = "I am here!"
  23. def print_info(self):
  24. print(f"哈哈哈,{self.str}")
  25. result = C()
  26. result.print_info() # 哈哈哈,I am here!

__mro__查看对象的继承关系

  1. print(对象.__mro__)
  2. 输出信息:子类 ==> 父类层级,即越靠右,其对应的父级层级越高。

子类调用父类的同名方法

子类调用父类的同名方法和属性:把父类的同名属性和方法再次封装即可

  • 在子类的方法中,如果先调用父类的属性和方法,父类属性会覆盖子类的属性,因此调用子类方法前,先调用子类的属性初始化
  • 调用父类的方法前,为保证调用的是父类的属性,必须在调用方法前调用父类的属性

——调用谁的方法,就先调用谁的属性

  1. # 父类A
  2. class A(object):
  3. def __init__(self):
  4. self.str = "hello world"
  5. def print_info(self):
  6. print(self.str)
  7. # 父类B
  8. class B(object):
  9. def __init__(self):
  10. self.str = "hi world"
  11. def print_info(self):
  12. print(self.str)
  13. # 子类C
  14. class C(A, B):
  15. def __init__(self):
  16. self.str = "I am here!"
  17. def print_info(self):
  18. self.__init__() # 先调用子类的属性初始化
  19. print(f"哈哈哈,{self.str}")
  20. # 子类调用父类的同名方法和属性:把父类的同名属性和方法再次封装
  21. def mainA(self):
  22. A.__init__(self) # 先调用父类的属性初始化
  23. A.print_info(self)
  24. def mainB(self):
  25. B.__init__(self) # 先调用父类的属性初始化
  26. B.print_info(self)
  27. result = C()
  28. result.print_info() # 哈哈哈,I am here!
  29. result.mainA() # hello world
  30. result.mainB() # hi world
  31. # print(C.__mro__)

多层继承(单继承)

  1. """继承方式: A ==> B ==> C ==>D """
  2. # 父类A
  3. class A(object):
  4. def __init__(self):
  5. self.str = "hello world"
  6. def print_info(self):
  7. print(self.str)
  8. # 父类B
  9. class B(object):
  10. def __init__(self):
  11. self.str = "hi world"
  12. def print_info(self):
  13. print(self.str)
  14. # 子类C
  15. class C(A, B):
  16. def __init__(self):
  17. self.str = "I am here!"
  18. def print_info(self):
  19. self.__init__() # 先调用子类的属性初始化
  20. print(f"哈哈哈,{self.str}")
  21. # 子类调用父类的同名方法和属性:把父类的同名属性和方法再次封装
  22. def print_parent(self):
  23. A.__init__(self) # 先调用父类的属性初始化
  24. A.print_info(self)
  25. B.__init__(self) # 先调用父类的属性初始化
  26. B.print_info(self)
  27. class D(C):
  28. pass
  29. result = D() # 孙继承类可以调用多个父级类的方法
  30. result.print_info() # 哈哈哈,I am here!
  31. result.print_parent() # hello world hi world

使用super()调用父类方法

**super()**函数可以自动查找父类。调用顺序遵循__mro__类属性的顺序,比较适合单继承。

  1. # 方法1(Python2):
  2. super(当前类名, 对象或类).xxx
  3. # 方法2(Python3):
  4. super().xxx
  5. 其中,第二个参数”对象或类“,一般使用self

单继承使用super()

  1. """继承方式: A ==> B ==> C ==> D """
  2. # 父类A
  3. class A(object):
  4. def __init__(self):
  5. self.num = 1
  6. def print_info(self):
  7. print(self.num)
  8. # 父类B
  9. class B(A):
  10. def __init__(self):
  11. self.num = 2
  12. def print_info(self):
  13. print(self.num)
  14. # 调用父级方法
  15. # 方法1:
  16. # super(B, self).__init__()
  17. # super(B, self).print_info()
  18. # 方法2:
  19. super().__init__()
  20. super().print_info()
  21. # 子类C
  22. class C(B):
  23. def __init__(self):
  24. self.num = 3
  25. def print_info(self):
  26. # self.__init__() # 先调用子类的属性初始化
  27. print(self.num)
  28. # 调用父级方法
  29. # 方法1:
  30. # super(C, self).__init__()
  31. # super(C, self).print_info()
  32. # 方法2:
  33. super().__init__()
  34. super().print_info()
  35. class D(C):
  36. pass
  37. result = D() # 孙继承类可以调用多个父级类的方法
  38. result.print_info() # 3 2 1

多继承使用super()

  1. """ 多继承方式----棱形继承
  2. ---> B ---
  3. A --| |--> D
  4. ---> C ---
  5. """
  6. class A(object):
  7. def __init__(self):
  8. print("Enter A")
  9. print("Leave A")
  10. class B(A):
  11. def __init__(self):
  12. print("Enter B")
  13. super().__init__()
  14. print("Leave B")
  15. class C(A):
  16. def __init__(self):
  17. print("Enter C")
  18. super().__init__()
  19. print("Leave C")
  20. class D(B, C):
  21. def __init__(self):
  22. print("Enter D")
  23. super().__init__()
  24. print("Leave D")
  25. # 创建对象
  26. d = D() # 创建对象时,自动调用类中的初始化属性
  27. """
  28. 执行结果如下:
  29. Enter D
  30. Enter B
  31. Enter C
  32. Enter A
  33. Leave A
  34. Leave C
  35. Leave B
  36. Leave D
  37. """

类的私有属性和方法

在Python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或方法不允许子类继承

  • 私有属性和私有方法只能在同一个类中访问和修改

    1. class 类名():
    2. # 私有属性
    3. __属性名 =
    4. # 私有方法
    5. def __函数名(self):
    6. 代码

    私有属性和方法示例

    ```python class A(): def init(self):

    1. self.str = "hello"
    2. self.__money = 100 # 私有属性

    def __print_info(self): # 私有方法

    1. print(self.str)
    2. print(self.__money)

class B(A): def init(self): self.str = “world”

  1. def print_info(self):
  2. print("haha")
  3. super().__init__()
  4. super().__print_info()

result = B() result.print_info() # 无法调用私有方法,报错

  1. <a name="rITSi"></a>
  2. ## 获取和修改私有属性值
  3. 在Python中,**一般定义函数名**`**get_xxx**`**用来获取私有属性,定义**`**set_xxx**`**用来修改私有属性**。
  4. - **私有属性和私有方法只能在同一个类中访问和修改**。
  5. ```python
  6. class A():
  7. def __init__(self):
  8. self.str = "hello"
  9. self.__money = 100
  10. def get_money(self): # 获取私有属性
  11. return self.__money
  12. def set_money(self): # 修改私有属性
  13. self.__money = 500
  14. def __print_info(self):
  15. print(self.str)
  16. print(self.__money)
  17. result = A()
  18. print(result.get_money()) # 100
  19. result.set_money()
  20. print(result.get_money()) # 500