>>> float(1.0) is float(1.0)
True
Это потому, что float
возвращает сам объект, потому что он уже float
(то же самое для строк BTW Следует ли мне избегать преобразования в строку, если значение уже является строкой? ).
Проверка исходного кода для подтверждения (с добавленными комментариями):
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
, вероятно, используется совместно при компиляции (это определяется реализациейи это единственное объяснение, которое я могу придумать, ответ Дюны объясняет это гораздо лучше), так что это то же самое, что 1.0 is 1.0
.
>>> float(1) is float(1)
False
Python должен создавать объекты с плавающей запятойдля каждой стороны, так что это разные.Не существует интернирования с плавающей запятой, например целых чисел.
И последняя забавная часть:
>>> id(float(1)) == id(float(2))
True
, потому что объект float
собирается мусором после вызова id
, поэтому id повторно , даже если литеральные значения отличаются , как показано в примере выше (как показано в Безымянный объект Python имеет тот же идентификатор или ПочемуИдентификатор класса Python не уникален при быстром вызове? ).