2010-11-12 23 views
8

Đây là cho Python 2.6.Đây có phải là lỗi không? Các biến là các tham chiếu giống nhau đến cùng một chuỗi trong ví dụ này (Python)

tôi không thể tìm ra lý do tại sao a và b là giống hệt nhau:

>>> a = "some_string" 
>>> b = "some_string" 
>>> a is b 
True 

Nhưng nếu có một không gian trong chuỗi, họ không:

>>> a = "some string" 
>>> b = "some string" 
>>> a is b 
False 

Nếu đây là hành vi bình thường, ai đó có thể vui lòng giải thích những gì đang xảy ra.

Chỉnh sửa: Từ chối trách nhiệm! Điều này không được sử dụng để kiểm tra sự bình đẳng. Tôi thực sự muốn giải thích cho người khác rằng "là" chỉ để kiểm tra danh tính, không bình đẳng. Và từ tài liệu tôi đã hiểu rằng các tham chiếu được tạo theo cách này sẽ khác nhau, rằng một chuỗi mới sẽ được tạo ra mỗi lần. Ví dụ đầu tiên tôi đã ném tôi ra khi tôi không thể chứng minh quan điểm của riêng tôi!

Edit: tôi hiểu rằng đây là không một lỗi, và thực tập là một khái niệm mới đối với tôi. This có vẻ là một lời giải thích tốt.

+0

xem http: // stackoverflow.com/questions/306313/python-is-operator-behaves-bất ngờ-với-số nguyên – cobbal

+0

"Lỗi?" Câu hỏi thực sự làm tôi khó chịu .. nhưng tôi đoán đó không phải là lý do để đánh dấu một câu hỏi ... phải không? – MattH

+0

@cobbal: Điều này hơi khác so với những gì đang diễn ra ở đây. –

Trả lời

10

Python có thể hoặc có thể không tự động chuỗi thực tập, mà sẽ xác định xem trường hợp tương lai của chuỗi sẽ chia sẻ một tài liệu tham khảo.

Nếu nó quyết định thực hiện một chuỗi, thì cả hai sẽ tham chiếu đến cùng một cá thể chuỗi. Nếu không, nó sẽ tạo ra hai chuỗi riêng biệt có cùng nội dung.

Nói chung, bạn không cần phải lo lắng về việc liệu điều này có xảy ra hay không; bạn thường muốn kiểm tra sự bình đẳng, a == b, cho dù chúng là cùng một đối tượng, a is b.

+0

+1 thực sự rõ ràng – Ant

+1

Chỉ cần ra khỏi tò mò, bạn có biết logic là gì khi Python thực tập dây? Tôi nghĩ rằng nó interned mỗi chuỗi chữ nhưng dường như không ... – katrielalex

+0

@ katrielalex: Strings từ một tập tin .py là một chút khác nhau: chúng được lưu trữ trong một danh sách các hằng số được gọi bằng chỉ số trong bytecode. Điều đó có nghĩa rằng nếu bạn sử dụng cùng một chuỗi liên tục ở hai nơi trong một tệp .py, nó gần như chắc chắn rằng chúng sẽ là cùng một đối tượng. Đó là khác với interning. Tuy nhiên, OP không chạy ra khỏi tệp .py, anh ta chạy từ trình thông dịch Python; điều đó có nghĩa là chúng được phân tách thành "tệp" riêng biệt và không có bảng chuỗi được chia sẻ. –

1

TIM PETERS SAID: Xin lỗi, lỗi duy nhất tôi thấy ở đây là trong mã bạn đã đăng bằng cách sử dụng "is" để thử xác định xem hai chuỗi có bằng nhau hay không. "là" các phép kiểm tra đối với nhận dạng đối tượng, không phải cho sự bình đẳng, và liệu hai đối tượng bất biến có thực sự là cùng một đối tượng không được định nghĩa chung bởi Python. Bạn nên sử dụng "==" để kiểm tra hai chuỗi cho sự bình đẳng. Thời gian duy nhất nó đáng tin cậy để sử dụng "là" cho mục đích đó là khi bạn đã rõ ràng interned tất cả các chuỗi được so sánh (thông qua việc sử dụng internin() nội chức năng).

từ đây: http://mail.python.org/pipermail/python-bugs-list/2004-December/026772.html

+0

-1: đối với các đối tượng không thay đổi như chuỗi bạn mong đợi các tham chiếu bằng nhau, vì vậy đây không phải là lỗi. – Falcon

+0

@ Falcon: Không. Chuỗi đó là bất biến * cho phép * (hiệu quả) interning (= tham chiếu giống hệt nhau cho các đối tượng giống nhau), nhưng nó không yêu cầu nó. – delnan

+0

@Falcon: Bạn sẽ bị nhầm lẫn với kỳ vọng đó. Kiểm tra sự bình đẳng giữa mã python gốc và thư viện c-python, ví dụ: thư viện openssl. Đó là ngay cả khi bạn không biết rằng không phải tất cả các chuỗi được thực tập. Xấu hổ tôi không thể đánh dấu bạn xuống. – MattH

0

Điều này thực sự sẽ có nhiều nhận xét hơn cho câu trả lời của Gleen nhưng tôi chưa thể đưa ra nhận xét. Tôi đã chạy một số bài kiểm tra trực tiếp trên trình thông dịch Python và tôi thấy một số hành vi thú vị. Theo Glenn, thông dịch viên coi các mục là "tệp" riêng biệt và chúng không chia sẻ một bảng chuỗi khi được lưu trữ để tham khảo trong tương lai. Dưới đây là những gì tôi chạy:

>>> a="some_string" 
>>> b="some_string" 
>>> id(a) 
2146597048 
>>> id(b) 
2146597048 
>>> a="some string" 
>>> b="some string" 
>>> id(a) 
2146597128 
>>> id(b) 
2146597088 
>>> c="some string" <-----(1) 
>>> d="some string" 
>>> id(c) 
2146597208   <-----(1) 
>>> a="some_string" 
>>> b="some_string" 
>>> id(a) 
2146597248   <---- waited a few minutes 
>>> c="some_string" 
>>> d="some_string" 
>>> id(d) 
2146597248   <---- still same id after a few min 
>>> b="some string" 
>>> id(b) 
2146597288 
>>> b="some_string" <---(2) 
>>> id(b) 
2146597248   <---(2) 
>>> a="some" 
>>> b="some" 
>>> c="some" 
>>> d="some"   <---(2) lost all references 
>>> id(a) 
2146601728 
>>> a="some_string" <---(2) 
>>> id(a) 
2146597248   <---(2) returns same old one after mere seconds 
>>> a="some" 
>>> id(a) 
2146601728   <---(2) Waited a few minutes 
>>> a="some_string" <---- (1) 
>>> id(a) 
2146597208   <---- (1) Reused a "different" id after a few minutes 

Dường như một số các tài liệu tham khảo id có thể được tái sử dụng sau khi tham khảo ban đầu bị mất và không còn là "sử dụng" (1), nhưng nó cũng có thể liên quan đến thời gian những tài liệu tham khảo id không được sử dụng, như bạn có thể nhìn thấy trong những gì tôi đã đánh dấu là số (2), cho các tham chiếu id khác nhau tùy thuộc vào bao lâu mà id đã không được sử dụng. Tôi chỉ thấy nó tò mò và nghĩ đến việc đăng nó.

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