当前位置: 首页 > 面试题库 >

为什么当[[]是[]“而'{}是{}'返回False时,'()是()'返回True?

颛孙庆
2023-03-14
问题内容

据我所知,使用[], {}()实例化对象分别返回list, dict或的新实例tuple。具有 新标识 的新实例对象。

在我实际测试它之前,这对我来说是很清楚的,我注意到它() is ()实际上返回了True而不是预期的False

>>> () is (), [] is [], {} is {}
(True, False, False)

如预期的那样,分别使用和创建对象时list(),也会表现出这种行为:dict()tuple()

>>> tuple() is tuple(), list() is list(), dict() is dict()
(True, False, False)

我可以在状态文档中tuple()找到唯一相关的信息:

[…]例如,tuple('abc')return('a', 'b', 'c')tuple([1, 2, 3])return (1, 2, 3)如果未提供任何参数,则构造函数将创建一个新的空元组()

可以说,这不足以回答我的问题。

那么,为什么空元组具有相同的标识,而其他元组(如列表或字典)却没有相同的标识呢?


问题答案:

简而言之:

Python在内部创建一个C元组对象列表,其第一个元素包含空元组。每次使用tuple()或时(),Python都会返回上述C列表中包含的现有对象,而不创建新对象。

相反,这种机制并不存在,dict或者 每次都从头开始重新创建的list对象都不存在。 __

这很可能与以下事实有关:不变的对象(例如元组)无法更改,因此保证在执行期间不会更改。考虑到frozenset() is frozenset()回报True,这一点得到进一步巩固;像()空一样frozenset
被认为是实现的单例CPython。对于可变对象,
此类保证没有到位 ,因此也没有动机来缓存其零元素实例(即,其内容可能会在身份保持不变的情况下发生变化)。

请注意: 这不是一个应该依靠的东西,即,一个人不应该将空元组视为单例。 在文档中没有明确保证此类保证,因此应假定它与实现有关。

怎么做的:

在最常见的情况下,的实现CPython是用两个宏编译的,PyTuple_MAXFREELISTPyTuple_MAXSAVESIZE设置为正整数。这些宏的正值会导致创建具有size的tuple对象数组PyTuple_MAXSAVESIZE

PyTuple_New使用参数调用时,请size == 0确保将新的空元组添加到列表(如果尚不存在):

if (size == 0) {
    free_list[0] = op;
    ++numfree[0];
    Py_INCREF(op);          /* extra INCREF so that this is never freed */
}

然后,如果请求一个新的空元组,则将返回位于该列表的第一位置的一个元组,而不是一个新的实例:

if (size == 0 && free_list[0]) {
    op = free_list[0];
    Py_INCREF(op);
    /* rest snipped for brevity.. */

促使这样做的另一个原因是函数调用构造了一个元组来保存将要使用的位置参数的事实。可以在以下load_args函数中看到ceval.c

static PyObject *
load_args(PyObject ***pp_stack, int na)
{
    PyObject *args = PyTuple_New(na);
    /* rest snipped for brevity.. */

do_call在同一文件中通过调用。如果参数个数na为零,则将返回一个空的元组。

本质上,这可能是一个经常执行的操作,因此不要每次都构造一个空的元组是有意义的。



 类似资料:
  • 为什么以下输出为True? 这将始终输出,即使条件似乎表明并非如此。如果我删除括号,那么它可以工作,但我不明白为什么。

  • 问题内容: 我找到了JavaDoc的方法: 返回:如果此线程已被中断,则返回true;否则返回false。 否则为假。 我对这种方法的理解有误。此外,我可能会误解Thread中的“中断”概念。 欢迎任何解释!谢谢! 程式码片段: 在线程定义中: 调用: 问题答案: 引发异常后,线程不再处于中断状态。

  • 在.NET Framework 4.5中,由Trim()方法调用的专用TrimHelper()方法使用以下条件来确定是否需要修剪字符:(由.NET Reflector反编译的代码) 我想知道为什么IsBOMWhitesspace方法总是返回false?? 这是微软计划在未来改变/扩展的吗?例如,通过检查char是否为‘u efff’并在这种情况下返回true?

  • 问题内容: 这怎么可能? 这是 您会看到它应该在这里: 到底是怎么回事? 问题答案: (此答案中的代码已针对Swift 3及更高版本进行了更新。) 显然,您的变量是a (描述文件路径)。要以字符串形式获取路径,请使用属性,而不是: 以字符串格式(包括方案等)返回URL 。 例:

  • PHP手册说,如果锁定成功,调用flock将返回TRUE,否则返回FALSE。若文件被其他进程阻塞,那个么flock应该等到它被解锁(因为我们不使用LOCK_NB)。文档中没有超时,超时会中断等待,所以显然flock将无限等待,直到获得锁为止。 但是有时我在我的多线程脚本中从flock()得到FALSE。那是什么原因呢?

  • 问题内容: 如果某些列返回FALSE,如何显示不同的值, 例如, COLUMN“ BASIC”返回FALSE,但我需要为用户显示YES或NO。情况为FALSE,请返回NO。 问题答案: 如果是varchar或bit,则处理NULL 或者如果只是一点点 编辑: