Nếu một đối tượng float
được cung cấp cho float()
, CPython * chỉ trả về nó mà không cần tạo một đối tượng mới.
Điều này có thể được nhìn thấy trong PyNumber_Float
(cuối cùng được gọi là từ float_new
) trong đó đối tượng o
được chuyển vào được chọn với PyFloat_CheckExact
; nếu True
, nó chỉ làm tăng số tham chiếu của nó và trả về nó:
if (PyFloat_CheckExact(o)) {
Py_INCREF(o);
return o;
}
Kết quả là, các id
của đối tượng vẫn như cũ. Vì vậy, sự biểu hiện
>>> float(0.0) is float(0.0)
suy biến thành
>>> 0.0 is 0.0
Nhưng tại sao mà bằng True
? Vâng, CPython
có một số nhỏ tối ưu hóa.
Trong trường hợp này, nó sử dụng cùng một đối tượng cho hai lần xuất hiện 0.0
trong lệnh của bạn vì chúng là một phần của the same code
object (tuyên bố từ chối trách nhiệm ngắn: chúng nằm trên cùng một đường logic); để kiểm tra is
sẽ thành công.
này có thể được chứng thực hơn nữa nếu bạn thực hiện float(0.0)
trong dòng riêng biệt (hoặc, giới hạn bởi ;
) và sau đó séc sắc:
a = float(0.0); b = float(0.0) # Python compiles these separately
a is b # False
Mặt khác, nếu một int
(hoặc một str
) được cung cấp, CPython sẽ tạo một đối tượng mới float
từ đó và trả lại điều đó. Đối với điều này, nó sử dụng tương ứng PyFloat_FromDouble
và PyFloat_FromString
.
Hiệu quả là các đối tượng quay trở lại khác nhau về id
s (mà sử dụng để kiểm tra nhân dạng với is
):
# Python uses the same object representing 0 to the calls to float
# but float returns new float objects when supplied with ints
# Thereby, the result will be False
float(0) is float(0)
* Lưu ý: Tất cả các hành vi nêu trước đó áp dụng cho thi hành python trong C
tức là CPython
. Các triển khai khác có thể thể hiện hành vi khác nhau. Tóm lại, không phụ thuộc vào nó.
Liên quan: http://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is-in-python – Elazar
Câu hỏi của bạn xứng đáng được trả lời, nhưng nếu bạn gặp phải vấn đề này trong mã thực, mã có lẽ là sai và phải được sửa. Có (hầu như) không có lý do để kiểm tra danh tính tham chiếu giữa các phao theo cách như vậy. – Elazar
Điều kỳ lạ là, mặc dù tôi có thể tạo lại điều này, tất cả 'id (0.0)', 'id (float (0.0))' và 'id (float (0))' trả lại cùng một giá trị. ... Đó là, giá trị là như nhau nếu tôi thực thi cái kia sau cái kia trong hệ vỏ tương tác, nhưng nếu tôi làm 'id (float (0.0)), id (float (0))' (như một bộ tuple) thì các id khác nhau. Có lời giải thích nào không? –