大于 256 且小于 -5 的数字的整数缓存 [英] Integer caching for numbers greater than 256 and less than -5

查看:22
本文介绍了大于 256 且小于 -5 的数字的整数缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道python有一个小整数的概念,它是从-5256的数字,如果两个变量分配给这个范围内的相同数字,它们都将使用相同的底层对象.

来自 Python 文档,

#ifndef NSMALLPOSINTS#define NSMALLPOSINTS 257#万一#ifndef NSMALLNEGINTS#define NSMALLNEGINTS 5#万一

<块引用>

/* 小整数预先分配在这个数组中,以便它们可以被分享.预先分配的整数是那些在范围 -NSMALLNEGINTS(包含)到 NSMALLPOSINTS(不包含).*/

还有在此解释,

<块引用>

当前的实现为所有对象保留了一个整数对象数组-5 到 256 之间的整数,当您在该范围内创建 int 时实际上只是取回对现有对象的引用.所以应该可以改变 1 的值.我怀疑这种行为在这种情况下,Python 是未定义的.:-)

示例,

a = 255乙 = 255打印(ID(一))打印(ID(b))

给出相同的id,

15618543940961561854394096

这是有道理的,也解释了这个答案,是"运算符对整数的行为出乎意料

如果两个数字小于-5,它们也应该有不同的ID,如下所示,

a = -6b = -6打印(ID(一))打印(ID(b))

给予,

28274260322082827426032272

到目前为止,这是有道理的,

但是任何大于256的数字都应该有不同的id

这应该返回不同的 ID,

a = 257乙 = 257打印(ID(一))打印(ID(b))

但是没有

21776752801122177675280112

即使我使用非常大的整数,ID 也是一样的,

a = 2571299123876321621378b = 2571299123876321621378打印(ID(一))打印(ID(b))

给我,

19568261391841956826139184

谁能告诉我为什么大于 256 的数字具有相同的 ID,即使在 Python 代码中的范围是 -5257(不包括)

我尝试在 Python 2.7 和 3.6 中使用 PyCharm.也在 PythonTutor.com 上试过

解决方案

在 Mint Python 3.6.3(也是 2)上,我无法重现.我的猜测是 PyCharm 或 pythontutor 在解释之前将运行包装起来 - 因为那些不是开放代码,我们看不到内部结构,所以我无法验证.我认为这是真的的原因是(下面的所有内容都是 mint Python 3):

<预><代码>>>>x=2571299123876321621378>>>y=2571299123876321621378>>>打印(id(x),id(y))140671727739528 140671727739808

你可以拥有这个:

<预><代码>>>>def bla():... x=2571299123876321621378... y=2571299123876321621378... id(x)...打印(id(x),id(y))...>>>布拉()140671727742528 140671727742528

因此将两个整数包装在解释器可以编译的东西中允许这些额外的优化 - 比如对两个定义使用相同的常量.请注意,这也是有限的:

<预><代码>>>>def bla():... x=2571299123876321621378... y=2571299123876321621378...打印(id(x),id(y))... x+=1... y+=1...打印(id(x),id(y))...>>>布拉()140671727755592 140671727755592140671728111088 140671728108808

我不会有任何依赖于此的代码 - 保证仅在 -5 到 256 之间.

I know that python has a concept of small integers which are numbers from -5 to 256, and if two variables assign to same numbers between this range, they both will use the same underlying object.

From Python documentation,

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS           257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS           5
#endif

/* Small integers are preallocated in this array so that they can be shared. The integers that are preallocated are those in the range -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive). */

Also explained here,

The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined. :-)

Example,

a = 255
b = 255
print(id(a))
print(id(b))

gives the same id,

1561854394096
1561854394096

Which makes sense and also explained on this answer, "is" operator behaves unexpectedly with integers

If two numbers are less than -5, they should also have different IDs as follows,

a = -6
b = -6
print(id(a))
print(id(b))

gives,

2827426032208
2827426032272

this makes sense so far,

But any number greater than 256 should have different id,

This should return different IDs,

a = 257
b = 257
print(id(a))
print(id(b))

But it doesn't

2177675280112
2177675280112

Even when I am using very large integer, the IDs are same,

a = 2571299123876321621378
b = 2571299123876321621378
print(id(a))
print(id(b))

gives me,

1956826139184
1956826139184

Can someone tell me why number greater than 256 have same IDs even though in the Python code the range is -5 to 257 (not inclusive)

EDIT:

I have tried using PyCharm with both Python 2.7 and 3.6. Also tried on PythonTutor.com

解决方案

On mint Python 3.6.3 (2 as well) I cannot reproduce. My guess is PyCharm or pythontutor are wrapping the run in something before interpreting - since those are not open code we cannot see the internals so I cannot verify. The reason I think this is true, is while (everything below is mint Python 3):

>>> x=2571299123876321621378
>>> y=2571299123876321621378
>>> print(id(x),id(y))
140671727739528 140671727739808

You can have this:

>>> def bla():
...  x=2571299123876321621378
...  y=2571299123876321621378
...  id(x)
...  print(id(x),id(y))
...
>>> bla()
140671727742528 140671727742528

so wrapping the two integers in something the interpreter can compile allows for these extra optimizations - like using the same constant for both definitions. Note this is limited as well:

>>> def bla():
...  x=2571299123876321621378
...  y=2571299123876321621378
...  print(id(x),id(y))
...  x+=1
...  y+=1
...  print(id(x),id(y))
...
>>> bla()
140671727755592 140671727755592
140671728111088 140671728108808

I would not have code that depends on this on any way - the guarantee is only on -5 to 256.

这篇关于大于 256 且小于 -5 的数字的整数缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆