2016-03-04 16 views
11

W python 3.5, czy można przewidzieć, kiedy otrzymamy internowany ciąg znaków lub kiedy otrzymamy kopię? Po przeczytaniu kilku odpowiedzi związanych z przepełnieniem stosu w tym wydaniu znalazłem this one najbardziej przydatne, ale wciąż nie wyczerpujące. Niż Spojrzałem na Python docs, ale interning nie jest gwarantowana domyślnieJakie są reguły interakcji ciągów cpython?

Normalnie, nazwy stosowane w programach Pythona są automatycznie internowany i słowniki używane do przechowywania modułu, klasy lub instancji atrybuty zostały internowane klawiatura.

Więc moje pytanie jest o wewnętrznych intern() warunkach, czyli podejmowania decyzji (czy stażysta Łańcuch znaków lub nie): dlaczego ten sam kawałek kodu działa w jednym systemie, a nie na inny i jakie zasady zrobił autor w odpowiedzi na mentioned topic myśli, gdy mówią

zasady, kiedy to nastąpi są dość zawiłe

+0

Po prostu użyj '==' i zapomnij o tym. W każdym razie jest to szczegół implementacji. – wim

+3

@erip Wierzę, że OP jest tego świadomy. Po przejściu przez płytę główną, pytanie to wydaje się pytać o zasady interwencji. – timgeb

+1

Jeśli naprawdę chcesz poznać różnice w implementacji, prawdopodobnie byłoby sensowne określenie wersji Pythona zainstalowanych w obu systemach. –

Odpowiedz

3

Myślisz, że są zasady?

Jedyna zasada interningu to internowana wartość zwracana przez intern. Wszystko inne zależy od kaprysów tego, kto zdecydował, że jakiś kodeks powinien lub nie powinien interweniować. Na przykład, "left" zostaje internowany przez 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)); 
} 

„zasada” jest to, że obiekt String w co_consts obiektu kodu Pythona zostaje internowany jeżeli składa się wyłącznie ze znaków ASCII, które są legalne w identyfikatorem Pythona . "left" zostanie internowany, ale "as,df" nie będzie, a "1234" będzie internowany, nawet jeśli identyfikator nie może zaczynać się od cyfry. Chociaż identyfikatory mogą zawierać znaki spoza ASCII, takie znaki są nadal odrzucane przez to zaznaczenie. Rzeczywiste identyfikatory nigdy nie przechodzą przez ten kod; zostają bezwarunkowo internowani kilka linii w górę, ASCII lub nie. Ten kod może ulec zmianie, a jest mnóstwo innych kodów, które obsługują lub interderopodobne rzeczy.

Zapytanie nas o "zasady" dotyczące interlinii ciągów jest jak zapytanie meteorologa o zasady, czy pada na ślubie. Możemy powiedzieć wiele o tym, jak to działa, ale nie będzie to dla ciebie przydatne, a zawsze będziesz miał niespodzianki.

+1

Tak. Jak zwykle z detalami implementacyjnymi, ** RTFS ** jest jedyną odpowiedzią naprawdę .. – wim

-3

z tego, co zrozumiałem z postu, który powiązany:

Podczas korzystania if a == b, jesteś sprawdzenie czy wartość a jest wartość b, natomiast podczas korzystania if a is b, jesteś sprawdzenie czy a i b to ten sam obiekt (lub dzielić to samo miejsce w pamięci).

Teraz python interns ciągłe ciągi (określone przez "blabla"). Więc:

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

Ale kiedy to zrobić:

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

w języku programowania C, wykorzystując ciąg z "" uczyni to const char *. Myślę, że właśnie to się tutaj dzieje.