为什么使用描述符可以引入__slots __?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么使用描述符可以引入__slots __?相关的知识,希望对你有一定的参考价值。

在“ Python的历史”系列的this blog post中,Guido van Rossum指出:

描述符的另一项增强是在类上引入了__slots__属性。

我将这句话理解为:__slots__是由描述符实现的。

但是与我的解释相反,Guido van Rossum稍后写了几行:

在幕后,此功能的实现完全用C语言完成,并且非常高效。

所以,__ slots__不是由描述符实现的吗?

但过了两句话,他再次写道:

不仅__lots__是描述符的有趣应用,...

所以,__ slots__和描述符实际上是什么情况?

__ slots__是否由描述符实现?如果是,怎么办?

答案

这些声明并不矛盾。 __slots__定义的属性是所创建类上的描述符,该描述符的实现是用C编写的(假定CPython)。

该描述符类称为member_descriptor,如以下示例代码所示:

import inspect

class Test:
    __slots__ = 'a',
    def __init__(self, a):
        self.a = a

type(Test.a)                        # member_descriptor
inspect.isdatadescriptor(Test.a)    # True
inspect.ismemberdescriptor(Test.a)  # True

并且在GitHub上的CPython存储库中进行的快速搜索显示the C implementation of it (Link for CPython version 3.8.0)


进入更多细节:

Python类本质上是一个dict,带有(很多)风铃。另一方面,有些Python-C类使用C- struct来实现Python类。即使仅包含Python对象(基本上是一个包含对Python对象的引用的C数组),这种C结构也比字典更快,并且(显着)需要的内存更少。

为了使“常规” Python类可以从更快的访问中受益,并减少了内存占用__slots__。具有__slots__的类将基本上转换为C结构。但是,为了使属性查找/设置/删除映射到相应的struct成员成为可能,需要某种翻译层(描述符)。 __slots__中定义的成员的翻译层为member_descriptor

因此,当您在__slots__类的实例上查找属性时,将获得member_descriptor,并且member_descriptor将知道如何获取/设置/删除基础C- [C0的成员]。

另一答案

考虑一个简单的类:

以上是关于为什么使用描述符可以引入__slots __?的主要内容,如果未能解决你的问题,请参考以下文章

8.python之面相对象part.8(__slots__属性)

item repr doc format slots doc module class 析构 call 描述符 开发规范

python面向对象高级

__slots__ 的使用?

python slots源码分析

__slots__(三十六)