Zmienne w Pythonie- prośba o wyjaśnienie

0

Dzień dobry, po wywołaniu funkcji id() otrzymuje następujący wynik:




liczba=10
liczba1=10
print(id(liczba))
print(id(liczba1))

1781835852368
1781835852368

Nie wiem czy dobrze zdefiniuje problem, ale spróbuję.
Dla dwóch różnych nazw z tą samą wartością, Python
zwraca ten sam adres w pamięci. Czyli, rozumiem, że nazwy liczba i liczba1 wskazują na ten sam obiekt.
Czy to taka specyfika języka że po inicjalizacji różnych nazw tą sama wartością, wskazują one tylko jedna „szufladkę” w pamięci- wspólną dla dwóch nazw?
Z góry dziękuję za pomoc.

0

To jest jakas tam optymalizacja bo int i tak jest niemutowalny (liczba+1 tworzy nowy obiekt). Nie zawsze tak bedzie.

W szczegolnosci jak zrobisz

p1 = Person("Jon", "Doe")
p2 = Person("Jon", "Doe")

to referencje beda wskazywac na cos innego.

EDIT: Mozesz zrobic liczba += 1 i zobaczysz ze zmieni sie tylko jedna zmienna :)

3

@crispia: W przypadku integerów poniżej jakiejś wartości - nie pamiętam dokładnie jakiej - python przypisuje zmiennym o danej wartości inta tą samą referencję.

6

Taka jest optymalizacja integerów, dla liczb od -5 do 256:

The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.

https://docs.python.org/3/c-api/long.html

Więcej tego typu "zaskakujących" sytuacji, tutaj:
https://github.com/satwikkansal/wtfpython

0

Dziękuję za pomoc. Mam jeszcze jedno pytanie. W sieci spotkałem się z takim stwierdzeniem: „Python w momencie przypisania wartości jednej zmiennej do innej nie tworzy kopii obiektu na który wskazuje zmienna, zamiast tego przypisuje referencję do istniejącego obiektu.”
Czy istnieje różnica pomiędzy tymi zapisami przypisania wartości :

liczba=10
liczba1=10

a:




liczba=10
liczba1=liczba
0

Dziękuję za pomoc. Mam jeszcze jedno pytanie. W sieci spotkałem się z takim stwierdzeniem: „Python w momencie przypisania wartości jednej zmiennej do innej nie tworzy kopii obiektu na który wskazuje zmienna, zamiast tego przypisuje referencję do istniejącego obiektu.”
Czy istnieje różnica pomiędzy tymi zapisami przypisania wartości :

liczba=10
liczba1=10

a:




liczba=10
liczba1=liczba
1

Tak.. Istnieje

liczba = 300
liczba1 = 300
id(liczba)
#140681923420816
id(liczba1)
#140681923421040
liczba1 = liczba
id(liczba1)
#140681923420816

Nie wiem czy zrozumiales to co wczesniej pisalismy

2

https://docs.python.org/3/library/functions.html#id

Ta funkcja wcale nie musi zwracać żadnego adresu w pamięci! Przypadkiem ma to miejsce dla CPythona ale nic poza tym.

0

Nie wiem czy zrozumiałeś to co wcześniej pisaliśmy


liczba = 300
liczba1 = 300
id(liczba)
#140681923420816
id(liczba1)
#140681923421040
liczba1 = liczba
id(liczba1)
#140681923420816

Nie wiem czy dobrze zrozumiałem. Z twojego kodu wynika, ze po po takim przypisaniu:


liczba = 300
liczba1 = 300

Tworzone są dwa różne obiekty, wskazuje na to różna wartość zwracana przez funkcję id:


#140681923420816      dla liczba
#140681923421040      dla liczba1

Po przypisaniu wartości liczba do liczba1 , nie jest tworzony nowy obiekt tylko referencja do już istniejącego obiektu liczba.

id(liczba1)
#140681923420816

Taka jest optymalizacja integerów, dla liczb od -5 do 256:
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.

U mnie w PyScripter otrzymuje coś takiego:


liczba=300
liczba1=300
print(id(liczba))
print(id(liczba1))
liczba1=liczba
print(id (liczba1))

1629399437616
1629399437616
1629399437616

Czyli nie są tworzone dwa obiekty, tylko jeden. Jest na to jakieś wytłumaczenie?
Pozdrawiam :)

1
crispia napisał(a):

Jest na to jakieś wytłumaczenie?

Radziłbym dać spokój ze śledzeniem tożsamości obiektów niemutowalnych (jak właśnie liczby). Skoro są niemutowalne, to ich tożsamość nie powinna mieć znaczenia i należy je porównywać == a nie is (wyjątkiem jest zalecany w Pythonie idiom is None/is not None).

Wiem, to nie jest żadne wytłumaczenie. :) Ale wytłumaczeniem jest to, że skoro jest tak, jak pisałem wyżej, to kompilator/interpreter/maszyna wirtualna może sobie zrobić jak chce -- tworzyć nowy obiekt niemutowalny albo wiązać do starego. Zależnie, jak twórcom wydaje się lepiej/wygodniej/szybciej... No i może być różnie w różnych wersjach (i nie należy tego uznawać za błąd lub coś dziwnego).

Co innego obiekty mutowalne -- ale nie o tym jest ten wątek.

3

By ująć to, co koszalek-opalek powiedział innymi słowami — to, jakie id będą miały obiekty, jest implementation dependent. Żaden standard Pythona nie mówi, jak ma być, zatem nie powinno się polegać na konkretnej implementacji — te mogą bowiem różnie do tego podchodzić.

1 użytkowników online, w tym zalogowanych: 0, gości: 1