子类中的 __slots__ 继承实际上是如何工作的?

2023-12-29

In the 关于槽的 Python 数据模型参考部分 http://docs.python.org/reference/datamodel.html#slots有一个关于使用的注释列表__slots__。我对第 1 条和第 6 条感到非常困惑,因为它们似乎相互矛盾。

第一项:

  • 当从没有的类继承时__slots__, the __dict__属性 那个班级的永远是 可访问,因此__slots__子类中的定义是 无意义的。

第六项:

  • 的行动__slots__声明仅限于类 它是在哪里定义的。因此, 子类将有一个__dict__除非他们也定义__slots__(必须仅包含任何名称 额外的插槽)。

在我看来,这些项目可以更好地措辞或通过代码显示,但我一直在努力解决这个问题,但仍然感到困惑。我确实明白如何__slots__ are 应该使用 https://stackoverflow.com/questions/472000/python-slots/472024#472024,我正在努力更好地了解它们是如何工作的。

问题:

有人可以用通俗易懂的语言向我解释一下子类化时继承槽的条件是什么吗?

(简单的代码示例会有所帮助,但不是必需的。)


正如其他人提到的,定义的唯一原因__slots__是为了节省一些内存,当您有具有一组预定义属性的简单对象并且不希望每个对象都带有字典时。当然,这仅对于您计划拥有许多实例的类才有意义。

节省的费用可能不会立即显现出来——考虑一下……:

>>> class NoSlots(object): pass
... 
>>> n = NoSlots()
>>> class WithSlots(object): __slots__ = 'a', 'b', 'c'
... 
>>> w = WithSlots()
>>> n.a = n.b = n.c = 23
>>> w.a = w.b = w.c = 23
>>> sys.getsizeof(n)
32
>>> sys.getsizeof(w)
36

由此看来,带槽尺寸是larger比无槽尺寸!但这是一个错误,因为sys.getsizeof不考虑“对象内容”,例如字典:

>>> sys.getsizeof(n.__dict__)
140

由于字典本身就需要 140 个字节,因此显然是“32 字节”对象n据称采取的行动并未考虑到每个案件所涉及的所有内容。您可以使用第三方扩展做得更好,例如pympler https://github.com/pympler/pympler:

>>> import pympler.asizeof
>>> pympler.asizeof.asizeof(w)
96
>>> pympler.asizeof.asizeof(n)
288

这更清楚地显示了所节省的内存占用量__slots__:对于像本例这样的简单对象,它略小于 200 字节,几乎占对象总体占用空间的 2/3。现在,由于如今对于大多数应用程序来说,多或少兆字节并不那么重要,这也告诉您__slots__如果您一次只有几千个实例,那么就不值得这么麻烦——但是,对于数百万个实例,它确实会产生非常重要的影响。您还可以获得微观的加速(部分是由于更好地使用小对象的缓存)__slots__):

$ python -mtimeit -s'class S(object): __slots__="x","y"' -s's=S(); s.x=s.y=23' 's.x'
10000000 loops, best of 3: 0.37 usec per loop
$ python -mtimeit -s'class S(object): pass' -s's=S(); s.x=s.y=23' 's.x'
1000000 loops, best of 3: 0.604 usec per loop
$ python -mtimeit -s'class S(object): __slots__="x","y"' -s's=S(); s.x=s.y=23' 's.x=45'
1000000 loops, best of 3: 0.28 usec per loop
$ python -mtimeit -s'class S(object): pass' -s's=S(); s.x=s.y=23' 's.x=45'
1000000 loops, best of 3: 0.332 usec per loop

但这在某种程度上取决于 Python 版本(这些是我使用 2.5 重复测量的数字;使用 2.6,我发现相对优势更大__slots__ for setting一个属性,但根本没有,确实是一个很小的属性dis优势,对于getting it).

现在,关于继承:对于一个无字典的实例,all其继承链上的类也必须具有无字典的实例。具有无字典实例的类是那些定义__slots__,加上大多数内置类型(实例具有字典的内置类型是您可以在其实例上设置任意属性的类型,例如函数)。插槽名称的重叠是不被禁止的,但它们是无用的并且浪费一些内存,因为插槽是继承的:

>>> class A(object): __slots__='a'
... 
>>> class AB(A): __slots__='b'
... 
>>> ab=AB()
>>> ab.a = ab.b = 23
>>> 

如您所见,您可以设置属性a on an AB实例 -AB本身只定义了slotb,但它继承了slota from A。不禁止重复继承的槽:

>>> class ABRed(A): __slots__='a','b'
... 
>>> abr=ABRed()
>>> abr.a = abr.b = 23

但确实浪费了一点内存:

>>> pympler.asizeof.asizeof(ab)
88
>>> pympler.asizeof.asizeof(abr)
96

所以真的没有理由这样做。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

子类中的 __slots__ 继承实际上是如何工作的? 的相关文章

随机推荐

  • 无法建立SSL连接,请参阅配置Github Self-Hosted Runner时的内部异常

    我正在研究 Github Enterprise 实例 并且当我尝试按照以下步骤向我的 GitHub 企业实例添加新的自托管运行器时 设置 操作 运行器 创建 自托管运行器我的组织的目录中 我在配置步骤中收到如下所示的错误 config sh
  • Spring-Cloud Zuul 破坏转发的多部分请求文件名中的 UTF-8 符号

    这是我第一次上SO 所以请耐心回答我的第一个问题 我认为我有某种配置问题 但经过一天的实验后我陷入困境 我们的应用程序基于 Spring Cloud Brixton 版本 我们有这样的配置 Portal 服务于基于角度的 Web UI 的
  • 在 Grails 中配置 Postgres

    我有一个迁移到 MySQL 和 PostgreSQL 的应用程序 并且在数据分配方面有不同的行为 通过分析在 Postgres 中创建的数据库 我意识到每个表中创建的 ID 编号不会因另一个表的更改而重置 例如 它被设置在寄存器3 Tabl
  • 无法安装调试器 gem - Rails - Mac OSX Mavericks

    我正在尝试在本地运行应用程序 但是当我这样做时 我会抛出此错误 Patricks MacBook Air niet pbj rails s Could not find debugger 1 6 1 in any of the source
  • pandas散点图绘制日期时间

    我有一个包含两列 datetime time 的数据框 我想将它们分散绘制 理想情况下 我还希望轴显示时间 但 df plot kind scatter x T1 y T2 转储一堆以 T1 上的 KeyError 结尾的内部绘图错误 或者
  • 如何配置express.js/jade处理html文件?

    我想配置 jade 引擎来处理视图文件夹中的 html 文件 这是我当前的服务器配置 app configure function var pub dir dirname public app set port process env PO
  • 在 virtualenv 中安装 pysvn

    我可以使用二进制包在站点范围内安装 pysvn 例如 在 Ubuntu 中 sudo apt get install python svn 或者 在 Windows 上 我可以使用 exe 安装程序进行站点范围内的安装 在 virtuale
  • 检查 Laravel 中的验证是否失败

    我想知道使用这种代码编写验证何时失败 我正在使用拉拉维尔 5 4 https laravel com docs 5 4 this gt validate request name gt required min 2 max 255 我知道我
  • 联系人选择器显示号码、联系人姓名以及可能的联系人图像?

    有没有办法显示同时包含号码和联系人姓名的联系人选择器 现在我正在调用选择器 startActivityForResult new Intent Intent ACTION PICK Contacts Phones CONTENT URI 1
  • 使用异或的 GetHashCode() 问题

    我的理解是 您通常应该将 xor 与 GetHashCode 一起使用来生成 int 以通过其值 而不是通过其引用 来识别数据 这是一个简单的例子 class Foo int m a int m b public int A get ret
  • OpenCV 在函数内更改 Mat(Mat 范围)

    我将 Mat 传递给另一个函数并在被调用函数内更改它 我原以为作为一个更复杂的类型 它会自动通过引用传递 以便矩阵在调用函数中发生变化 但事实并非如此 有人可以向我指出如何从函数正确返回更改后的 Mat 的解释吗 这是代码片段 void c
  • 已弃用的 CLRegion 方法 - 如何获取半径?

    我正在使用geocodeAddressString completionHandler 方法 它返回 CLPlacemarks 数组 我必须获取纬度 经度 助记名和半径 虽然获得前 3 个很容易 double lat placemark l
  • OpenFire Server 中用户的 JID 应该是什么?

    您好 我对此很陌生 我已经设置了一个 Openfire 服务器并使用 Spark IM 来测试它 但对于 Android 应用程序代码 会话中用户的 JID 应该是 我尝试过 username ip address username ip
  • 在 Windows Phone 7 上将数据保存到独立存储的最佳方式是什么?

    我想将对象持久化到独立存储中 到目前为止我可以想到这些方法 保存时将它们序列化为 xml 文件 然后在保存时将它们序列化回来 使用对象数据库 对好的或推荐的怀疑比比皆是 例子是Perst http wmpoweruser com fully
  • 如何验证 okhttp 是否使用 http/2 进行请求?

    如何验证 okhttp 是否成功协商 http 2 并且没有使用 https 1 1 我可以检查回复中的一些信息吗 谢谢 托尼 仅供参考 从 okhttp 3 0 左右开始OkHttp Selected Protocol未打印 不过 可以在
  • 从服务 android 更新我的活动中的列表视图

    我有两节课 1 活动课 2 服务等级 当服务有任何更新时 我需要更新活动中的列表视图 实际上我尝试像聊天应用程序一样 我的服务总是检查我的数据库 如果它有任何新字符串 我需要在我的活动中更新而无需再次重建 只需刷新列表视图 我发现它将使用
  • 悬停时的原型 Element.toggle,禁用子元素

    我遇到以下情况 我有一个这样的表结构 tr td text td td text td td text td td a href img src a td td span style display hidden a href e a a
  • VRML 发生了什么?

    早在 20 世纪 90 年代末 当我在读研究生时 VRML 即将占领世界 我和我的同事通过将其连接到 Java 和 Javascript 代码 用它构建了各种有用且有趣的东西 当然 当时的计算机比现在慢很多倍 多核 CPU 很大程度上是科幻
  • 使用 CreateProcessWithLogonW 进行作业控制

    我正在编写的应用程序需要在主机系统上执行潜在的恶意代码 该代码仅与stdin stdout and stderr 并且不应尝试与文件系统或网络交互 我通过防火墙规则限制了网络访问 并通过以非特权用户身份运行该进程来限制文件系统访问NetUs
  • 子类中的 __slots__ 继承实际上是如何工作的?

    In the 关于槽的 Python 数据模型参考部分 http docs python org reference datamodel html slots有一个关于使用的注释列表 slots 我对第 1 条和第 6 条感到非常困惑 因为