详细分析Python中的__slots__基本知识(附Demo)

1. 基本知识

__slots__ 是 Python 类中的一个特殊属性,用于限制实例可以动态添加的属性,并减少内存占用

一、没有__slots__ 情况:
当类没有定义 __slots__ 时,每个实例会有一个默认的字典(__dict__)来存储对象的属性
意味着可以动态添加属性,并且每个实例的内存使用会稍微多一些,因为需要存储字典

特点:

  • 灵活性高,可以动态添加属性
  • 由于使用字典存储属性,内存占用较多
  • 属性访问速度较慢,因为字典查找涉及哈希计算

二、有__slots__ 的情况:

不再为每个实例创建 __dict__,而是直接使用一种更紧凑的数据结构来存储属性

这可以显著减少内存使用,但限制了动态添加属性

特点:

  • 节省内存,因为不需要为每个实例存储字典
  • 限制动态添加未在 __slots__ 中定义的属性
  • 属性访问速度更快,因为直接引用而非字典查找

基本的总结如表所示:

特性没有 __slots____slots__
内存使用较高,使用字典存储属性较低,使用更紧凑的数据结构
动态添加属性允许不允许,除非在 slots 中定义
属性访问速度较慢较快
灵活性
__dict__ 属性是否存在存在不存在
使用场景需要动态添加属性的类内存优化和确定属性的类

2. Demo

没有使用的情况:

class NoSlots:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 创建实例
obj1 = NoSlots("Alice", 30)

# 动态添加属性
obj1.gender = "Female"

print(obj1.__dict__)  # {'name': 'Alice', 'age': 30, 'gender': 'Female'}

使用的情况:

class WithSlots:
    __slots__ = ['name', 'age']
    
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 创建实例
obj2 = WithSlots("Bob", 25)

# 尝试动态添加属性
try:
    obj2.gender = "Male"
except AttributeError as e:
    print(e)  # 'WithSlots' object has no attribute 'gender'

截图如下:

在这里插入图片描述

再者 __slots__ 的继承

class Parent:
    __slots__ = ['name']

    def __init__(self, name):
        self.name = name


class Child(Parent):
    __slots__ = ['age']

    def __init__(self, name, age):
        super().__init__(name)
        self.age = age


# 创建实例
obj3 = Child("Charlie", 10)

# 尝试动态添加属性
try:
    obj3.gender = "Male"
except AttributeError as e:
    print(e)  # 'Child' object has no attribute 'gender'

截图如下:

在这里插入图片描述

所以说

子类的 __slots__ 属性是父类的 __slots__ 和子类的 __slots__ 的组合
仍然无法动态添加 gender 属性

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农研究僧

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值