知行编程网知行编程网  2023-01-13 05:30 知行编程网 隐藏边栏  1 
文章评分 0 次,平均分 0.0
导语: 本文主要介绍了关于Python3中类属性slots的常见疑问有哪些?的相关知识,希望可以帮到处于编程学习途中的小伙伴

Python3中类属性槽的常见问题有哪些?

电脑用久了,内存会慢慢不够用,操作起来会比较慢。与其想着增加电脑的内存,不如换个思路,如何释放电脑的内存。 python3中的槽是用来减少内存占用的,但是大家知道使用的时候要注意什么吗?小编今天把需要注意的地方都整理出来了,一起来看看吧。


1.为什么 __slots__ 可以节省内存,提高速度的?


2.

咋通过 __slots__ 来实现属性的存储与访问的?


3

.

使用__slots__的类如何实现动态赋值,如果需要弱实例引用支持怎么办?



4

.

使用了 __slots__ 的类继承与被继承时的表现?



针对这几个问题作答:

1. 通常,类实例使用 __dict__ 来存储它的属性数据。好处是它允许我们在运行时动态设置实例属性。但是dict哈希表本身的数据结构决定了它需要更多的内存。当创建的实例越多,或者实例的属性越多,内存消耗就会越严重。 __slots__ 确保解释器在编译时知道这个类有哪些属性,并分配一个固定的空间来存储已知的属性。


2.使用 __slots__ 时,会将属性的存储从实例的 __dict__ 改为类的 __dict__ 中:

>>> Y.__dict__
mappingproxy({'__module__': '__main__',
              '__slots__': ('a', 'b'),
              '__init__': <function __main__.Y.__init__(self, a, b)>,
              'a': <member 'a' of 'Y' objects>,
              'b': <member 'b' of 'Y' objects>,
              '__doc__': None})



属性访问是通过在类级别为每个槽变量创建和实现一个描述符来实现的,它知道属性值在实例列表中的唯一位置。描述符和属性的访问在我的文章Into the Inside of a Python Class中有详细讲解,感兴趣的同学可以阅读。另外,this how __slots__ implemented 可能会帮助你理解,虽然我觉得是很多年前写的了,但还是有参考意义的。






3.如何实现动态赋值和弱引用支持?答案是:将__dict__ 和__weakref__ 添加到__slots__。

class Y:
    __slots__ = ('a', 'b', '__dict__', '__weakref__')
 
    def __init__(self, a, b):
        self.a = a
        self.b = b
>>> import weakref
>>> y = Y(7, 8)
>>> y.a
7
>>> y.b
8
>>> y.c = 9
>>> y.__dict__
{'c': 9}
>>> ry = weakref.ref(y)
>>> ry
<weakref at 0x107d17d68; to 'Y' at 0x107a4d480>

4.当一个类继承自一个没有定义__slots__的类时,该实例的__dict__和__weakref__属性将始终是可访问的。

class X:
    def __init__(self):
        self.a = 7
 
class Y(X):
    __slots__ = ('b', 'c')
 
    def __init__(self):
        super().__init__()
        self.b = 8
        self.c = 9
>>> y = Y()
>>> y.a
7
>>> y.b
8
>>> y.__dict__
{'a': 7}

5.父类中声明的__slots__在其子类中也可用。但是,子类将获得 __dict__ 和 __weakref__ 除非它们还定义了 __slots__ 。

class X:
    __slots__=('a', 'b')
 
    def __init__(self):
        self.a = 7
        self.b = 8
 
class Y(X):
    """没有定义 __slots__"""
 
class Z(X):
    __slots__ = ()
>>> y = Y()
>>> y.a
7
>>> y.b
8
>>> y.c = 9
>>> y.__dict__
{'c': 9}
 
>>> z = Z()
>>> z.a
7
>>> z.b
8
>>> z.c = 9
AttributeError: 'Z' object has no attribute 'c'

看来想要成功给电脑释放内存并不是一件容易的事情,这些常见的slots疑问点大家一定要牢记哦~

更多Python学习推荐:



本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享