Another duplicate đã hỏi tại sao hai chuỗi bằng nói chung là không giống nhau, đó là không thực sự trả lời ở đây:
>>> x = 'a'
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False
Vì vậy, tại sao chúng không phải là cùng một chuỗi? Đặc biệt trong bối này:
>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True
Hãy trì hoãn phần thứ hai cho một chút. Làm sao người đầu tiên có thể đúng?
Trình thông dịch sẽ phải có "bảng interning", bảng ánh xạ chuỗi giá trị đối tượng chuỗi, vì vậy mỗi khi bạn cố gắng tạo chuỗi mới với nội dung 'abc'
, bạn sẽ lấy lại cùng một đối tượng. Wikipedia có một cuộc thảo luận chi tiết hơn về cách thức hoạt động của interning.
Và Python có bảng chuỗi ký tự; bạn có thể thực hiện chuỗi theo cách thủ công bằng phương pháp sys.intern
.
Thực tế, Python được cho phép tự động thực hiện bất kỳ loại bất biến nào, nhưng không phải yêu cầu để làm như vậy. Các triển khai khác nhau sẽ tập trung các giá trị khác nhau.
CPython (triển khai bạn đang sử dụng nếu bạn không biết bạn đang sử dụng triển khai nào) tự động thực tập số nguyên nhỏ và một số đơn đặc biệt như False
, chứ không phải chuỗi (hoặc số nguyên lớn hoặc tuple nhỏ hoặc còn gì nữa không). Bạn có thể thấy điều này khá dễ dàng:
>>> a = 0
>>> a += 1
>>> b = 1
>>> a is b
True
>>> a = False
>>> a = not a
>>> b = True
a is b
True
>>> a = 1000
>>> a += 1
>>> b = 1001
>>> a is b
False
OK, nhưng tại sao là z
và w
giống hệt nhau?
Đó không phải là trình thông dịch tự động thực hiện, đó là giá trị gấp của trình biên dịch.
Nếu cùng một chuỗi thời gian biên dịch xuất hiện hai lần trong cùng một module (những gì chính xác điều này có nghĩa là khó có thể xác định-nó không phải là điều tương tự như một chuỗi chữ, vì r'abc'
, 'abc'
, và 'a' 'b' 'c'
là literals tất cả khác nhau nhưng cùng một chuỗi - nhưng dễ hiểu trực giác), trình biên dịch sẽ chỉ tạo một thể hiện của chuỗi, với hai tham chiếu.
Trong thực tế, trình biên dịch có thể đi xa hơn nữa: 'ab' + 'c'
có thể được chuyển đổi sang 'abc'
bởi tôi ưu hoa, trong trường hợp nó có thể được gấp lại với nhau với một 'abc'
liên tục trong các mô-đun tương tự.
Một lần nữa, đây là điều mà Python được phép nhưng không bắt buộc phải làm. Nhưng trong trường hợp này, CPython luôn gấp các chuỗi nhỏ (và cũng có thể, ví dụ, các bộ dữ liệu nhỏ). (Mặc dù tuyên bố theo tuyên bố biên dịch các thông dịch viên tương tác của không chạy tối ưu hóa tương tự như trình biên dịch module-at-a-thời gian, vì vậy bạn sẽ không nhìn thấy chính xác những kết quả tương tự tương tác.)
Vì vậy, , bạn nên làm gì với tư cách là một lập trình viên?
Chà ... không có gì. Bạn hầu như không bao giờ có bất kỳ lý do gì để quan tâm nếu hai giá trị bất biến là giống hệt nhau. Nếu bạn muốn biết khi nào bạn có thể sử dụng a is b
thay vì a == b
, bạn đang đặt câu hỏi sai. Chỉ cần luôn luôn sử dụng a == b
trừ hai trường hợp:
- Để so sánh dễ đọc hơn với các giá trị singleton như
x is None
.
- Đối với các giá trị có thể thay đổi, khi bạn cần biết liệu có đột biến
x
hay không sẽ ảnh hưởng đến y
.
Câu hỏi liên quan http://stackoverflow.com/questions/38189660/two-variables-in-python-have-same-id-but-not-lists-or-tuples-why/38189759#38189759 – Kasramvd