2016-03-04 29 views
11

Trong python 3.5, có thể dự đoán khi nào chúng ta sẽ nhận được một chuỗi nội bộ hoặc khi chúng ta sẽ nhận được một bản sao? Sau khi đọc một vài câu trả lời Stack Overflow về vấn đề này tôi đã tìm thấy this one hữu ích nhất nhưng vẫn không toàn diện. Hơn tôi nhìn Python docs, nhưng interning không được bảo đảm theo mặc địnhCác quy tắc cho chuỗi ký tự của cpython là gì?

thường, tên được sử dụng trong các chương trình Python sẽ được tự động thực tập nội trú, và các bộ từ điển sử dụng để tổ chức mô-đun, lớp hoặc trường hợp thuộc tính đã thực tập nội trú phím.

Vì vậy, câu hỏi của tôi là về intern() điều kiện bên trong, tức là đưa ra quyết định (cho dù là để thực tập chuỗi chữ hay không): tại sao cùng một đoạn mã hoạt động trên một hệ thống và không vào nhau và những gì quy tắc đã làm tác giả các câu trả lời trên mentioned topic nghĩa khi nói

quy tắc cho thời điều này xảy ra khá phức tạp

+0

Chỉ cần sử dụng '==' và quên nó đi. Đó là chi tiết triển khai. – wim

+3

@erip Tôi tin rằng OP nhận thức được điều đó. Sau khi nhận được thông qua các boilerplate, câu hỏi này dường như được hỏi về các quy tắc interning. – timgeb

+1

Nếu bạn thực sự muốn biết sự khác biệt trong việc triển khai, có lẽ sẽ có ý nghĩa khi chỉ định các phiên bản Python được cài đặt trên cả hai hệ thống. –

Trả lời

3

Bạn cho rằng có quy tắc?

Quy tắc duy nhất cho việc thực tập là giá trị trả lại của intern được thực hiện. Mọi thứ khác là tùy thuộc vào ý thích của bất kỳ ai quyết định một số đoạn mã nên hoặc không nên thực tập. Ví dụ, "left" được thực tập nội trú bởi PyCodeNew:

/* Intern selected string constants */ 
for (i = PyTuple_GET_SIZE(consts); --i >= 0;) { 
    PyObject *v = PyTuple_GetItem(consts, i); 
    if (!all_name_chars(v)) 
     continue; 
    PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i)); 
} 

Những "quy tắc" ở đây là một đối tượng chuỗi trong co_consts của một đối tượng mã Python được thực tập nội trú nếu nó bao gồm hoàn toàn các ký tự ASCII đó là hợp pháp ở một định danh Python . "left" được thực tập, nhưng "as,df" sẽ không được, và "1234" sẽ được lưu trữ ngay cả khi số nhận dạng không thể bắt đầu bằng chữ số. Mặc dù số nhận dạng có thể chứa các ký tự không phải ASCII nhưng các ký tự đó vẫn bị từ chối bởi kiểm tra này. Số thực tế không bao giờ chuyển qua mã này; họ nhận được một cách vô điều kiện một vài dòng lên, ASCII hay không. Mã này có thể thay đổi và có rất nhiều mã khác thực hiện nội dung giống như interning hoặc interning.

Yêu cầu chúng tôi cho "quy tắc" để thực hiện chuỗi giống như yêu cầu một nhà khí tượng học quy tắc cho dù trời mưa trên đám cưới của bạn. Chúng tôi có thể nói với bạn khá nhiều về cách thức hoạt động của nó, nhưng nó sẽ không được sử dụng nhiều cho bạn, và bạn sẽ luôn có những điều bất ngờ.

+1

Có. Như thường lệ với chi tiết thực hiện, ** RTFS ** là câu trả lời duy nhất thực sự .. – wim

-3

từ những gì tôi hiểu từ bài bạn liên kết:

Khi bạn sử dụng if a == b, bạn đang kiểm tra nếu giá trị của a là giá trị của b, trong khi đó khi bạn sử dụng if a is b, bạn đang kiểm tra nếu ab là cùng một đối tượng (hoặc chia sẻ cùng một chỗ trong bộ nhớ).

Bây giờ python thực hiện các chuỗi không đổi (được xác định bởi "blabla"). Vì vậy:

>>> a = "abcdef" 
>>> a is "abcdef" 
True 

Nhưng khi bạn làm:

>>> a = "".join([chr(i) for i in range(ord('a'), ord('g'))]) 
>>> a 
'abcdef' 
>>> a is "abcdef" 
False 

Trong ngôn ngữ lập trình C , sử dụng một chuỗi với "" sẽ làm cho nó một const char *. Tôi nghĩ rằng đây là những gì đang xảy ra ở đây.

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