2013-06-16 38 views
12

Theo như tôi biết, mọi thứ đều là đối tượng trong Python và id() nên (tôi có đúng không?) Trả lại một số khác nhau cho từng đối tượng.Cùng một giá trị cho id (float)

Trong trường hợp của tôi, id(1) lợi nhuận 4298178968, id(2) lợi nhuận 4298178944 nhưng tôi nhận được các giá trị tương tự cho tất cả các loại phao, id(1.1) lợi nhuận 4298189032, id(2.2) cũng trả 4298189032 và nhiều hơn nữa.

Tại sao tôi nhận được cùng một id cho tất cả giá trị float?

Trả lời

18

Python có thể sử dụng lại vị trí bộ nhớ.

Khi bạn chạy:

id(1.1) 

bạn tạo một giá trị float, xin id() của nó, và sau đó Python xóa giá trị một lần nữa bởi vì không có gì liên quan đến nó. Khi bạn sau đó tạo một giá trị float, Python có thể tái sử dụng các vị trí bộ nhớ tương tự và do đó id(2.2) có thể trả về giá trị tương tự cho id():

>>> id(1.1) 
140550721129024 
>>> id(2.2) 
140550721129024 

Làm điều này thay vì:

float_one, float_two = 1.1, 2.2 
print id(float_one), id(float_two) 

Bây giờ float giá trị có tham chiếu đến chúng (hai biến) và sẽ không bị phá hủy, và bây giờ họ có vị trí bộ nhớ khác nhau và do đó id() giá trị.

Lý do bạn thấy các giá trị id() khác nhau cho các số nguyên nhỏ (từ -5 đến 256) là vì these values are interned; Python chỉ tạo một đối tượng số1 số nguyên và tái sử dụng nó nhiều lần. Kết quả là, các số nguyên này đều có một địa chỉ bộ nhớ duy nhất, như trình thông dịch Python đã đề cập đến chúng, và sẽ không xóa chúng cho đến khi trình thông dịch thoát ra.

+0

Ah vâng, tôi đang ở trong ipython nơi các số được lưu trong Out! :) –

+0

Cảm ơn @MartijnPieters. – ehsandotnet

+0

Lưu ý rằng việc thực hiện các số nguyên nhỏ này có lẽ là một tính năng của CPython _implementation_ chứ không phải là một thuộc tính được bảo đảm của ngôn ngữ. Trong trường hợp này, nó tương tự như các giá trị NSInteger nhỏ (0 đến 12 từ bộ nhớ) trong một số triển khai Objective-C, nơi mọi người đã tự hỏi về số lượng giữ lại lạ. Và, như vậy, có lẽ không phải là một ý tưởng tốt để dựa vào việc thực tập này. – paxdiablo

4
>>> id(1.1) 
154154684 

Như 1.1 không được gán cho bất kỳ biến vì vậy nó được thu thập rác và thời gian tiếp theo cùng id sẽ được sử dụng cho một float:

>>> id(2.2) 
154154684 

tiết kiệm 1.1 trong một biến:

>>> f = 1.1 
>>> id(f) 
154154684 #this id is locked for now 

Bây giờ địa chỉ mới được sử dụng:

>>> id(1.1) 
154154700 
>>> id(2.2) 
154154700 

này áp dụng cho số nguyên cũng như:

>>> id(260) 
154302180 
>>> id(280) 
154302180 

Số nguyên từ -5 để 256 đang thực sự được lưu trữ trong python, vì vậy họ luôn luôn đi trở lại ID khác nhau.("is" operator behaves unexpectedly with integers)

Đối chuỗi:

Giống như nguyên một số chuỗi cũng được lưu trữ trong python. Vì vậy, id các chuỗi như vậy sẽ là khác nhau (Để biết chi tiết đọc: 'is' operator behaves differently when comparing strings with spaces):

>>> id('foo') 
162861592 
>>> id('foo') 
162861568 

chuỗi Non-chữ và số (sử dụng cùng id):

>>> id('foo!&9((&') 
162840000 
>>> id('foo!&9((&') 
162840000 
Các vấn đề liên quan