2015-03-05 15 views
8

Dlaczego zastosowanie dwukropka ma wpływ na wynik? A jaki powinien być poprawny wynik?Średnik w języku Python robi różnicę

# Not stored in a different location. 
>>> id('123 4')== id('123 4') 
True 

# Also returns true 
>>> x = '123 4'; y ='123 4'; id(x) == id(y) 
True 

Ale to samo zwraca false.

>>> x = '123 4' 
>>> y = '123 4' 
>>> id(x) == id(y) 
False 

samo pod zwraca True

>>> def test(): 
...  x = '123 4';y='123 4'; print (id(x)==id(y)) 
...  a = '123 4' 
...  b='123 4' 
...  print (id(a)==id(b)) 
... 
>>> test() 
True 
True 
+1

Czy linia x = '123 4'; y = "123 4"; id (x) == id (y) wykonać w jednym kroku, dlatego zwrócił true? –

+2

@ 61612 Nie uważam tego za duplikat wspomnianego pytania. Pytanie brzmi, dlaczego reguły interningowych ciągów różnią się, gdy używa się znak nowego wiersza i średnika jako separatora instrukcji. – luk32

+1

Nie, nie uważałem za duplikat. Obawiam się o inny wynik przy użyciu średnika w python. –

Odpowiedz

8
>>> x="123 4";y="123 4" 

Python jest wystarczająco inteligentny, aby rozpoznać obie zmienne uzyskać taką samą wartość (ponieważ są one interpretowane w tym samym wierszu) i tak przechowuje że wartość w tej samej lokalizacji pamięci (to znaczy id(x) == id(y)).

Jednak

>>> x="123 4" 
>>> y="123 4" 

Python nie jest wystarczająco silny, aby realizować oba są tej samej wartości (ponieważ są one interpretowane w osobnych liniach) i tak przechowuje każdy w swoim miejscu pamięci (czyli id(x) != id(y)).

+4

Czy jest to gdzieś określone, czy jest to jakieś magiczne i nieudokumentowane zachowanie, które ktoś starał się dodać do interpretera w języku Python? – ArtOfWarfare

+1

, ponieważ python parsuje wiersz po wierszu, może powiedzieć ... w C/C++ byłby zoptymalizowany przez kompilator ... jeśli zrobiłbyś "y = x", to podzieliłby się id ... jego po prostu jak Python przydziela pamięć ... wszystko pythona jest open source ... i jestem pewien, że możesz gdzieś znaleźć aktualną dokumentację (może tylko patrząc na źródło). –

+0

Myślę, że internowanie ciągu ma miejsce, gdy łańcuch jest analizowany. W tłumaczu jest to linia po linii. Odbiór nie polega na nieokreślonym zachowaniu! – tdelaney

4

To tylko przypadek, w jaki sposób napisano tłumacza. Robienie tego samego w skrypcie pokazuje inny wynik. Wydaje mi się, że internowanie ciągów odbywa się wzdłuż jednostek kompilacji.

(dodawane stuff2.py pokazać wielu modułów)

stuff2.py:

z = '123 4' 

stuff.py:

x = '123 4';y='123 4';print id(x)==id(y) 
x = '123 4' 
y='123 4' 
print id(x)==id(y) 
import stuff2 
print id(x)==id(stuff2.z) 


$ python stuff.py 
True 
True 
False 
+0

Wydaje mi się to dziwne - dlaczego robienie tego w scenariuszu ma inne zachowanie niż robienie tego w interpretorze? Oznacza to, że ktoś starał się napisać optymalizację, która jest wykonywana tylko w tłumaczu. – ArtOfWarfare

+3

Nie widzę tego w ten sposób. Wygląda na to, że obiekty internowania ciągów działają w ramach akcji parsującej, która jest inna w tłumaczu, który działa na małych fragmentach i wykonaniu skryptu, który działa na całym pliku. Kolejnym interesującym testem będzie to, co dzieje się w wielu modułach. Myślę, że dodam to. – tdelaney

+0

ahh lepiej niż moja odpowiedź (nie wiedziałem, że to było specyficzne dla uruchamiania interaktywnego) (+1 ode mnie) –

0

dobrze, jak jest to oczywiste, jest to związane z do wstawiania stringów w Python. Mechanizm ten jest zależny od implementacji, więc każdy interpreter języka Python, taki jak CPython, IronPython, PyPy itp., Może zachowywać się inaczej. I może się zmieniać między wersjami. Prawdopodobnie może nawet zmieniać się między biegami.

Aby rozwiązać konkretny przypadek, należy przeanalizować kod źródłowy danej wersji tłumacza. Najlepszym rozwiązaniem jest to, że istnieje niewielka różnica we wdrażaniu instrukcji przekazywanych w jednym wierszu (oddzielonych średnikiem) i wykonywaniu ich pojedynczo.

Podczas interaktywnego uruchamiania należy pamiętać, że pomiędzy poszczególnymi wierszami kodu może się wydarzyć wiele, ponieważ może zajść potrzeba sprawdzenia. Kiedy przekazujesz wszystko naraz, tłumacz ma o wiele mniej powodów do zmartwień, co może się wydarzyć między tymi stwierdzeniami.

0

Jeśli przypisać niezmienny obiekt do zmiennej w Pythonie zmienną, jak również punkty wartość na tym samym miejscu,

>>> a = 5 
>>> b = 5 
>>> id(5) 
11372376 
>>> id(a) 
11372376 
>>> id(b) 
11372376 
>>> a == b 
True 
>>> a is b 
True 

Porównanie ID będzie działać dokładnie jak widać wartości tożsamości. Teraz pozwala przypisać zmienne obiekty do zmiennych Pythona.

>>> x = '123 4' 
>>> y = '123 4' 
>>> x == y 
True 
>>> x is y 
False 
>>> id(x) 
21598832 
>>> id(y) 
21599408 
>>> id('123 4') 
21599312 

Tutaj można zobaczyć różnicę ID. jako "jest" porównuje wartości z lokalizacją adresu, gdzie jako "==" porównuje się bezpośrednio z wartością odniesienia.Jednak nie daje błędu w przypadku niezmiennych obiektów, ponieważ wszystkie wskazują na to samo położenie, ale w przypadku zmienności, ponieważ wartości mogą się zmieniać, zmienne są wskazywane na bieżący obiekt, a zatem daje on fałszywy wynik.

Nadzieja to pomaga :)