Python có một nhóm tất cả các chuỗi và chúng là các chuỗi đơn ở đó không?Các chuỗi được gộp chung trong Python
chính xác hơn, trong đoạn mã sau một hoặc hai chuỗi được tạo ra trong bộ nhớ:
a = str(num)
b = str(num)
?
Python có một nhóm tất cả các chuỗi và chúng là các chuỗi đơn ở đó không?Các chuỗi được gộp chung trong Python
chính xác hơn, trong đoạn mã sau một hoặc hai chuỗi được tạo ra trong bộ nhớ:
a = str(num)
b = str(num)
?
Strings là không thay đổi trong Python, vì vậy việc thực hiện có thể quyết định xem có nên thực tập (đó là một thuật ngữ thường gắn liền với C#, có nghĩa là một số chuỗi được lưu trữ trong một nhóm) hay không.
Trong ví dụ của bạn, bạn đang tạo chuỗi động. CPython không nhìn vào hồ bơi để phát hiện chuỗi đã có ở đó hay không - nó cũng không có ý nghĩa vì trước tiên bạn phải đặt trước bộ nhớ để tạo chuỗi và sau đó so sánh nó với nội dung hồ bơi (không hiệu quả cho chuỗi dài).
Nhưng đối với các chuỗi có độ dài 1, CPython không nhìn vào bể bơi (cf. "stringobject.c"):
static PyStringObject *characters[UCHAR_MAX + 1];
...
PyObject *
PyString_FromStringAndSize(const char *str, Py_ssize_t size)
{
...
if (size == 1 && str != NULL &&
(op = characters[*str & UCHAR_MAX]) != NULL)
{
#ifdef COUNT_ALLOCS
one_strings++;
#endif
Py_INCREF(op);
return (PyObject *)op;
}
...
Vì vậy:
a = str(num)
b = str(num)
print a is b # <-- this will print False in most cases (but try str(1) is str(1))
Nhưng khi sử dụng liên tục dây trực tiếp trong mã của bạn, CPython sử dụng cùng một cá thể chuỗi:
a = "text"
b = "text"
print a is b # <-- this will print True
@Andidog: Nếu CPython không nhìn vào hồ bơi để kiểm tra xem chuỗi đã có ở đó chưa, thì tại sao in a là b in đúng khi num bằng 5? – Brian
@Brian: Xin lỗi, đó là một chút không chính xác. Đã chỉnh sửa câu trả lời của tôi để giải thích cách thức CPython thực hiện điều đó. – AndiDog
Câu trả lời hay. Chi tiết duy nhất tôi muốn thêm là lưu ý rằng Python có 'intern()' – keturn
Chuỗi không được tập trung nói chung. Trong ví dụ của bạn, hai chuỗi sẽ được tạo (ngoại trừ các giá trị từ 0 đến 9). Để kiểm tra điều này chúng ta có thể sử dụng toán tử is
để xem nếu hai chuỗi là cùng một đối tượng:
>>> str(1056) is str(1056)
False
gì về điều này: Trong [1]: x = str (5) Trong [2]: y = str (5) Trong [3]: id (x) Out [3]: 3077925280L Trong [4]: id (y) Out [4]: 3077925280L ? – gruszczy
gruszczy: Đó là một câu hỏi hay. Đây là trường hợp đặc biệt chỉ áp dụng cho các con số từ 0 đến 9.Nói chung mặc dù, tuyên bố là không đúng sự thật. Tôi đã làm rõ câu trả lời của mình. –
0-9 là một trường hợp cụ thể trên một trình biên dịch cụ thể (mặc dù phải thừa nhận, đó là trình biên dịch hầu hết mọi người sử dụng). Các trình biên dịch khác có thể chọn một số chuỗi khác được xác định trước. – Brian
Nói chung, chuỗi không được thực tập nội trú bằng Python, nhưng họ đôi khi dường như là:
>>> str(5) is str(5)
True
>>> str(50) is str(50)
False
Đây không phải là không phổ biến bằng Python, nơi các đối tượng phổ biến có thể được tối ưu hóa theo những cách mà những người bình thường không:
>>> int(5+0) is int(5+0)
True
>>> int(50+0) is int(50+0)
True
>>> int(500+0) is int(500+0)
False
Và hãy nhớ, tất cả các loại chi tiết này sẽ khác nhau giữa các lần triển khai Python và thậm chí giữa các phiên bản của cùng một triển khai.
Chỉ để tham khảo, các chuỗi không thể là đơn. Một singleton là một lớp mà chỉ có thể có một cá thể, và cá thể đó phải được truy cập trên toàn cầu. Có thể (hy vọng) có nhiều trường hợp của lớp 'str'; do đó nó không phải là một singleton. – zneak
Khái niệm bạn đang tìm kiếm là thực hiện chuỗi: http://en.wikipedia.org/wiki/String_interning –
@zneak Cảm ơn bạn đã bình luận. Tôi có nghĩa là một cái gì đó như giá trị singleton (hồ bơi hoặc chuỗi interning là từ thích hợp cho nó - http://en.wikipedia.org/wiki/String_interning). –