问题描述
float(1.0) is float(1.0) #True
float(1) is float(1) #False
我将这里的float()奇异性与对象创建顺序隔离开了,因为
I've isolated the float() oddity here to the object creation order, because
x1 = float(1)
x2 = float(1)
x1 is x2 #False
id(x1) == id(x2) #False
y1 = float(1.0)
y2 = float(1.0)
y1 is y2 #True
id(y1) == id(y2) #True
注意:我已经检查了浮子的精度,这不是发生这种情况的原因.
Note: I've done checks on the precision of the floats and it is not the reason why this is happening.
我想了解Python为什么以及如何决定创建float对象.为什么当float(1.0)创建两次时,float(1.0)指向同一个对象,而float(1)却指向2个不同的对象?
I wish to understand why and how is Python deciding to create float objects.Why is float(1.0) pointing to the same object while float(1) points to 2 different objects when either are created twice?
此外,供进一步参考:
float(1) is float(1) #False
id(float(1)) == id(float(1)) #True
float(1.0) is float(1.0) #True
id(float(1.0)) == id(float(1.0)) #True
推荐答案
>>> float(1.0) is float(1.0)
True
那是因为float
返回对象本身,因为它已经是float
(对于字符串BTW ).
That's because float
returns the object itself because it's already a float
(same for strings BTW Should I avoid converting to a string if a value is already a string?).
检查源代码以确认(添加评论):
Checking the source code to confirm (with added comments):
static PyObject *
float_float(PyObject *v)
{
if (PyFloat_CheckExact(v)) // if v is already a float, just increase reference and return the same object
Py_INCREF(v);
else
// else create a new float object using the input value
v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval);
return v;
}
在编译时,文字1.0
上的引用可能会共享(定义了实现,这是我能想到的唯一解释,"Dunes answer "(沙丘答案解释得更好),所以它与1.0 is 1.0
一样.
And the reference on literal 1.0
is probably shared when compiled (that's implementation defined, and that's the only explanation I can think of, Dunes answer explains it much better), so it's the same as 1.0 is 1.0
.
>>> float(1) is float(1)
False
Python必须为每一侧创建浮点对象,因此有所不同.没有任何浮点数可以像整数一样进行遍历.
Python has to create floating point objects for each side, so it's different. There isn't any floating point interning like integers.
最后一个有趣的部分:
>>> id(float(1)) == id(float(2))
True
因为float
对象是在调用id
之后被垃圾回收的,所以id会重新使用 ,即使上面的示例中的字面值是不同显示(如未命名的Python对象具有相同的ID 或为什么是Python的ID该类在快速调用时不是唯一的吗?).
because the float
object is garbage collected after id
has been called, so id is reused, even if the literal values are different as the above example shows (as exposed in Unnamed Python objects have the same id or Why is the id of a Python class not unique when called quickly?).
这篇关于float()对象ID的创建顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!