Python类与对象的内存结构是怎样的?对象模型底层解析

来源:站长查询作者:桃乃木香奈头衔:网络博主
导读:本期聚焦于小伙伴创作的《Python类与对象的内存结构是怎样的?对象模型底层解析》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Python类与对象的内存结构是怎样的?对象模型底层解析》有用,将其分享出去将是对创作者最好的鼓励。

Python的类与对象体系是其面向对象特性的核心,理解其底层内存结构和对象模型,能帮助开发者更清晰地掌握属性查找、方法调用等行为的本质,避免开发中常见的认知误区。

Python类与对象的内存结构是怎样的?对象模型底层解析

Python对象模型的核心基础

Python中一切皆对象,无论是整数、字符串、函数还是类本身,都是对象。每个对象在内存中都包含三个核心部分:对象头、类型指针、对象体。对象头存储对象的引用计数和垃圾回收相关标记,类型指针指向该对象所属的类型对象,对象体存储对象的具体数据。

类本身也是对象,属于type类型的实例,而实例对象则是对应类对象的实例。这种层级关系构成了Python对象模型的基础。

类对象的内存结构

当定义一个类时,Python解释器会创建一个类对象,该类对象的内存中主要存储以下内容:

  • 类的属性字典__dict__,存储所有类属性、方法定义
  • 类的基类信息__bases__
  • 类的名称、模块等元信息
  • 指向type的类型指针

实例对象的内存结构

类实例化时创建的对象,内存中主要存储:

  • 实例的属性字典__dict__,仅存储实例独有的属性
  • 指向所属类对象的类型指针__class__
  • 对象头的相关信息

内存结构的代码验证

我们可以通过简单的代码观察类和实例的内存相关特性,以下示例基于CPython实现。

class Student:
    # 类属性
    school = "默认学校"
    
    def __init__(self, name):
        # 实例属性
        self.name = name
    
    def study(self):
        print(f"{self.name}正在学习")

# 创建两个实例对象
stu1 = Student("张三")
stu2 = Student("李四")

# 查看类对象的__dict__,包含类属性和方法
print("类Student的__dict__键:", list(Student.__dict__.keys()))
# 输出:['__module__', 'school', '__init__', 'study', '__dict__', '__weakref__', '__doc__']

# 查看实例对象的__dict__,仅包含实例属性
print("stu1的__dict__:", stu1.__dict__)  # {'name': '张三'}
print("stu2的__dict__:", stu2.__dict__)  # {'name': '李四'}

# 验证类属性和实例属性的存储差异
# 修改类属性,所有实例都会受影响
Student.school = "新学校"
print(stu1.school)  # 新学校
print(stu2.school)  # 新学校

# 给stu1添加实例独有的属性
stu1.age = 18
print("添加age后stu1的__dict__:", stu1.__dict__)  # {'name': '张三', 'age': 18}
# stu2没有age属性
print("stu2的__dict__:", stu2.__dict__)  # {'name': '李四'}

属性查找的内存逻辑

当访问一个对象的属性时,Python的查找顺序是先从实例对象的__dict__中查找,如果找不到,再到类对象的__dict__中查找,如果类有继承关系,还会按照继承链向上查找。

我们可以通过自定义__getattribute__方法观察这个查找过程:

class CustomClass:
    class_attr = "类属性值"
    
    def __init__(self):
        self.instance_attr = "实例属性值"
    
    def __getattribute__(self, item):
        print(f"尝试访问属性:{item}")
        # 调用父类的__getattribute__完成默认查找逻辑
        return super().__getattribute__(item)

obj = CustomClass()
print(obj.instance_attr)
# 输出:
# 尝试访问属性:instance_attr
# 实例属性值

print(obj.class_attr)
# 输出:
# 尝试访问属性:class_attr
# 类属性值

方法的内存存储与调用

类中定义的方法,默认存储在类对象的__dict__中,实例对象本身不存储方法。当实例调用方法时,Python会将实例作为第一个参数self传递给方法,这个过程是通过描述符协议实现的。

以下代码可以验证方法的存储位置:

class Demo:
    def func(self):
        pass

# 方法存储在类的__dict__中
print("func是否在Demo的__dict__中:", "func" in Demo.__dict__)  # True
# 实例的__dict__中没有func
d = Demo()
print("func是否在d的__dict__中:", "func" in d.__dict__)  # False

# 查看方法的类型
print(type(Demo.func))   # <class 'function'>
print(type(d.func))      # <class 'method'>

可以看到,类中的函数未绑定实例时类型是function,当通过实例访问时,会被包装成method类型,自动传入实例作为self参数。

内存优化的相关特性

Python为了减少实例对象的内存开销,提供了__slots__属性。当类中定义__slots__时,实例对象不再有__dict__,而是按照__slots__定义的属性列表分配固定大小的内存,仅存储指定属性。

class SlotStudent:
    __slots__ = ("name", "age")
    
    def __init__(self, name, age):
        self.name = name
        self.age = age

s = SlotStudent("王五", 20)
print("实例是否有__dict__:", hasattr(s, "__dict__"))  # False
# 无法动态添加__slots__之外的属性
try:
    s.grade = 3
except AttributeError as e:
    print("添加属性失败:", e)  # 'SlotStudent' object has no attribute 'grade'

这种方式适合需要创建大量实例的场景,能有效降低内存占用,但代价是失去了动态添加属性的灵活性。

总结

Python的类与对象内存结构遵循一切皆对象的设计理念,类对象存储类级别的属性和方法,实例对象仅存储自身独有的属性,通过类型指针关联所属类。属性查找遵循实例到类再到继承链的顺序,方法通过描述符协议实现实例绑定。理解这些底层逻辑,能帮助开发者更合理地设计类结构,在需要时选择合适的内存优化方案。

Python类与对象内存结构对象模型修改时间:2026-07-10 23:06:14

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。