2013-03-27 24 views
5

Hôm nay tôi biết rằng Python lưu trữ các biểu hiện {}, và thay thế nó bằng một dict trống mới khi nó được gán cho một biến:hành vi kỳ lạ liên quan đến bộ nhớ đệm rõ ràng của "{}"

print id({}) 
# 40357936 

print id({}) 
# 40357936 

x = {} 
print id(x) 
# 40357936 

print id({}) 
# 40356432 

Tôi có không nhìn vào mã nguồn, nhưng tôi có một ý tưởng về cách thực hiện điều này. (Có lẽ khi đếm tham chiếu đến toàn cầu {} được tăng lên, toàn cầu {} được thay thế.)

Nhưng xem xét bit này:

def f(x): 
    x['a'] = 1 
    print(id(x), x) 

print(id(x)) 
# 34076544 

f({}) 
# (34076544, {'a': 1}) 

print(id({}), {}) 
# (34076544, {}) 

print(id({})) 
# 34076544 

f đổi dict toàn cầu mà không gây ra nó phải được thay thế, và nó in ra các dict sửa đổi. Nhưng bên ngoài của f, mặc dù id là như nhau, các dict toàn cầu bây giờ là sản phẩm nào!

Điều gì đang xảy ra ??

+0

bạn cũng có thể quan tâm đến điều đó: http://stackoverflow.com/questions/15315096/why-the-id-of-an-object-would-change-depending-on-the-line-in-the -python-shell/15321863 # 15321863 – User

+0

Trường hợp cạnh rất mát mẻ, cảm ơn bạn đã chia sẻ. – dimo414

+0

'id()' của Python sử dụng một địa chỉ bộ nhớ (ít nhất là việc triển khai CPython) làm ID cho các đối tượng. Đó là một số nhận dạng duy nhất chỉ tại một thời điểm duy nhất, không phải là duy nhất trong toàn bộ thời gian của chương trình của bạn. Điều này rõ ràng trong tài liệu: http://docs.python.org/2/library/functions.html#id –

Trả lời

6

Nó không được lưu trong bộ nhớ cache - nếu bạn không chỉ định kết quả là {} ở bất kỳ đâu, số tham chiếu của nó là 0 và nó được làm sạch ngay lập tức. Nó chỉ xảy ra rằng một trong những kế tiếp bạn phân bổ tái sử dụng bộ nhớ từ cũ. Khi bạn gán nó cho x bạn giữ nó sống, và sau đó tiếp theo có địa chỉ khác.

Trong ví dụ chức năng của bạn, khi f trả về, không có tham chiếu nào còn lại cho dict của bạn, do đó nó cũng được xóa và điều tương tự cũng được áp dụng.

+0

Câu trả lời hay, cảm ơn vì đã giải thích rằng "bộ nhớ đệm" (mà tôi nghĩ là một sự tối ưu hóa khá đáng ngờ, dù sao) – valtron

4

Python không thực hiện bất kỳ bộ nhớ đệm nào tại đây. Có hai khả năng khi id() cho giá trị trả về cùng tại các điểm khác nhau trong một chương trình:

  1. id() được kêu gọi cùng một đối tượng hai lần
  2. Đối tượng đầu tiên mà id() đã kêu gọi được thu gom rác thải trước khi đối tượng thứ hai đã được tạo và đối tượng thứ hai được tạo ở cùng một vị trí bộ nhớ như là

trong trường hợp này, là đối tượng thứ hai. Điều này có nghĩa rằng mặc dù print id({}); print id({}) có thể in cùng một giá trị hai lần, mỗi cuộc gọi là trên một đối tượng riêng biệt.

Các vấn đề liên quan