为什么使用描述符可以引入__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 描述符 开发规范