文章目录
- [1. Python类中__new__和__init__的区别](#1. Python类中__new__和__init__的区别)
- [2. Python面向对象中继承的特点](#2. Python面向对象中继承的特点)
- [3. Super函数的作用](#3. Super函数的作用)
- [4. 简单说说MRO(方法解析顺序)](#4. 简单说说MRO(方法解析顺序))
- [5. Python中类方法、类示例方法、静态方法的区别](#5. Python中类方法、类示例方法、静态方法的区别)
- [6. 说说实例属性和类属性的区别](#6. 说说实例属性和类属性的区别)
1. Python类中__new__和__init__的区别
| 方法 | 作用 | 调用时机 | 返回值 |
|---|---|---|---|
__new__ |
创建实例对象 | 在对象实例化阶段最先被调用 | 必须返回实例对象(通常是 cls 的实例) |
__init__ |
初始化实例属性 | 在 __new__ 创建实例后调用 |
无返回值(返回 None) |
一句话总结:
__new__决定"对象是谁 ",__init__决定"对象长什么样"。
2. Python面向对象中继承的特点
继承是面向对象的核心特性之一:通过继承可以做到子类可以继承父类的属性和方法,实现代码复用和功能扩展。
特点:
- python中支持单继承和多继承。
- 子类可以继承父类属性和方法
- 子类可以重写父类方法
- 可以调用父类方法
- 对于多继承情况下Python使用 C3 线性化算法 决定查找顺序
3. Super函数的作用
super() 返回 父类(或上层类)的代理对象 ,通过它可以调用父类的 方法 或 属性。
super函数的主要用途:
- 调用父类方法,避免直接使用类名(更灵活)
- 解决多继承方法调用冲突(配合 MRO)
4. 简单说说MRO(方法解析顺序)
MRO(方法解析顺序)决定了 Python 在调用某个对象方法时,按照哪个顺序查找类及其父类的方法。
在单继承的情况下:
- MRO 很简单 → 直接从子类往父类查找
在多继承情况下:Python 使用 C3 线性化算法 来生成 MRO。C3优化算法保证一下特性
- 子类优先(子类方法覆盖父类方法)
- 父类继承顺序尊重声明顺序
- 保证单调性(父类在继承链中只出现一次)
python中可以通过类名.mro()查看MRO
简单示例
python
class A:
def foo(self): print("A.foo")
class B(A):
def foo(self):
print("B.foo")
super().foo()
class C(A):
def foo(self):
print("C.foo")
super().foo()
class D(B, C):
def foo(self):
print("D.foo")
super().foo()
d = D()
d.foo()
# 打印结果为
#D.foo
#B.foo
#C.foo
#A.foo
5. Python中类方法、类示例方法、静态方法的区别
实例方法:
- 默认方法,绑定实例
- 第一个参数必须是
self - 可以访问 实例属性 和 类属性
使用示例
python
class Demo:
class_attr = 100
def __init__(self, value):
self.value = value
def instance_method(self):
print(f"实例属性:{self.value}, 类属性:{Demo.class_attr}")
obj = Demo(10)
obj.instance_method()
类方法:
- 使用
@classmethod装饰 - 第一个参数必须是
cls(类本身) - 可访问
类属性,但不能直接访问实例属性 - 可以被类对象或实例对象调用
使用示例
python
class Demo:
class_attr = 100
@classmethod
def class_method(cls):
print(f"类属性:{cls.class_attr}")
Demo.class_method() # 类调用
obj = Demo()
obj.class_method() # 实例调用
静态方法
- 使用
@staticmethod装饰 - 不绑定类或实例
- 没有
self或cls参数 - 类似普通函数,但放在类中组织逻辑
使用示例
class Demo:
@staticmethod
def static_method(x, y):
print(f"计算结果:{x + y}")
Demo.static_method(3, 4) # 类调用
obj = Demo()
obj.static_method(5, 6) # 实例调用
三种方法对比
| 特性 | 实例方法 | 类方法 | 静态方法 |
|---|---|---|---|
| 第一个参数 | self | cls | 无 |
| 是否可访问实例属性 | 可以 | 不可以 | 不可以 |
| 是否可访问类属性 | 可以 | 可以 | 可以(通过类型) |
| 调用方式 | 实例对象 | 类和实例对象 | 类或实例 |
6. 说说实例属性和类属性的区别
先看看实例属性和类属性分别是如何定义的
python
class Demo:
class_attr = 100 # 类属性
def __init__(self, value):
self.instance_attr = value # 实例属性
两种属性的区别对比:
| 特性 | 实例属性 | 类属性 |
|---|---|---|
| 绑定对象 | 绑定 实例对象 | 绑定 类对象 |
| 存储位置 | 每个实例单独存储 | 所有实例共享同一个属性 |
| 访问方式 | instance.attr |
Class.attr 或 instance.attr |
| 修改影响 | 仅影响当前实例 | 所有实例可见(除非被实例覆盖) |
| 典型用途 | 存储对象状态 | 存储类状态或常量 |