【问题标题】:Is the empty tuple in Python a "constant" [duplicate]Python中的空元组是“常量”吗?
【发布时间】:2017-02-01 15:13:21
【问题描述】:

我想让我的代码更有效率(内存)。现在我们有很多以可迭代作为参数的函数,例如:

def foo(para,meter,iterable):
    #...
    pass

有时我们必须为它提供一个空列表才能正常工作:foo(14,25,[])。问题是每次构造一个新列表时:它需要在堆上分配,并且一个列表似乎有 64 个字节的内存(在我自己的机器上,用sys.getsizeof([]) 测试)而只有空元组 占用(可能一次)48 个字节。

因此我想知道空元组是否是一个常数。由于元组是不可变的,因此可以很容易地使长度为0(所以())的元组在程序中成为一个常数。这将减少“构造时间”(没有,因为它只会设置对常量的引用)并减少分配的内存量。

我的问题是,是否有关于 Python 解释器(即任何流行的解释器)的保证,即空元组确实是一个常量,因此 () 不需要构建时间,也不需要分配额外的内存。

id(..) 测试它似乎支持确实只有一个零元组的理论:

>>> id(())
140290183798856
>>> a = ()
>>> id(a)
140290183798856

但有可能在运行时 Python 解释器出于某种原因分叉了元组。

【问题讨论】:

  • @vaultah:问题不是为什么。我认为这个问题清楚地表明我知道它是如何在幕后工作的。问题是它是否总是持有() is ()
  • 我认为 Jim 的回答也涵盖了这一点?
  • @vaultah:是的,但我上次去看医生时我的眼睛没问题,我看到 重复 question,而不是 duplicate answer :) 不幸的是,比利时的教育只提供了在中学学习五种语言的机会,所以我不能排除解释完全错误的可能性。
  • @WillemVanOnsem:如果另一个问题的答案也回答了这个问题,那么副本就可以了。吉姆的回答肯定与我相呼应。

标签: python memory tuples python-internals


【解决方案1】:

在 CPython 中,空元组是单例。永远只创建一个副本,然后在您使用 () 或在空生成器上使用 tuple() 时重复使用。

PyTuple_new() function 本质上是这样做的:

if (size == 0 && free_list[0]) {
    op = free_list[0];
    Py_INCREF(op);
    // ...
    return (PyObject *) op;
}

因此,如果元组大小为 0(空)并且存在 free_list[0] 对象(现有的空元组单例),则使用它。

有关free_list的更多详细信息,请参阅How is tuple implemented in CPython?; CPython 还将重用已创建的 tuple 实例,长度不超过 20。

这是一个实现细节。其他实现(Jython、IronPython、PyPy)不必这样做。

【讨论】:

    猜你喜欢
    • 2014-12-16
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 2017-10-14
    • 2015-06-29
    • 1970-01-01
    • 2017-02-02
    相关资源
    最近更新 更多