python怎么返回true_python – 为什么'()is()’返回True当'[]是[]’和'{}是{}’返回False?...

简而言之:

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

对于dict或list对象,不存在这种机制,相反,它们每次都从头开始重新创建。

这很可能与以下事实有关:不可变对象(如元组)不能被改变,并且因此保证在执行期间不改变。当考虑frozenset()是frozenset()返回True时,这进一步固化; like()一个空的frozenset is considered an singleton in the implementation of CPython.对于可变对象,这样的保证不在位,因此,没有动机缓存其零元素实例(即,它们的内容可能改变与身份保持不变)。

注意:这不是一个应该依赖的,即不应该将空元组视为单例。在文档中没有明确做出这样的保证,所以应该假定它是依赖于实现的。

如何做:

在最常见的情况下,CPython的实现编译有两个宏PyTuple_MAXFREELIST和PyTuple_MAXSAVESIZE设置为正整数。这些宏的正值导致创建一个大小为PyTuple_MAXSAVESIZE的array of tuple objects。

当使用参数size == 0调用PyTuple_New时,如果它不存在,确保add a new empty tuple到列表:

if (size == 0) {

free_list[0] = op;

++numfree[0];

Py_INCREF(op); /* extra INCREF so that this is never freed */

}

然后,如果请求一个新的空元组,位于first position of this list的那个将被返回,而不是一个新的实例:

if (size == 0 && free_list[0]) {

op = free_list[0];

Py_INCREF(op);

/* rest snipped for brevity.. */

导致激励这样做的另一个原因是函数调用构造一个元组来保存将要使用的位置参数。这可以在ceval.c中的load_args函数中看到:

static PyObject *

load_args(PyObject ***pp_stack, int na)

{

PyObject *args = PyTuple_New(na);

/* rest snipped for brevity.. */

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

实质上,这可能是一个频繁执行的操作,所以每次不重建一个空的元组是有意义的。

进一步阅读:

几个更多的答案阐明了CPython的缓存行为与不可变:

>对于整数,在源中挖掘的另一个答案可以找到here。

>对于字符串,可以找到几个答案here,here和here。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值