2010-03-25 51 views
8

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) 

?

+4

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

+10

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 –

+0

@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). –

Trả lời

16

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 
+0

@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

+0

@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

+3

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

1

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 
+1

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

+0

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

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

5

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.

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