Discussion:
Wskaźniki w pythonie
(Wiadomość utworzona zbyt dawno temu. Odpowiedź niemożliwa.)
kurcze
2007-01-26 11:25:07 UTC
Permalink
Z pythonem mam do czynienia od niedawna (jestem początkujący).
Zastanawia mnie, czy jest sposób żeby utworzyć wskaźnik do danego
obiektu czy typu (np. float), tak aby po zmianie wartości zmiennej, na
którą wskazuje, wskaźnik dalej wskazywał na tą zmienną. Uff... trochę
zamieszałem :), mam nadzieję, że wiecie co mam na myśli.
x = 1
y = x
x = 2
x
2
y
1
A chcę, żeby y dalej wskazywało na wartość x

Pozdrawiam, kurcze
Piotr Chamera
2007-01-26 16:05:56 UTC
Permalink
Post by kurcze
Z pythonem mam do czynienia od niedawna (jestem początkujący).
Zastanawia mnie, czy jest sposób żeby utworzyć wskaźnik do danego
obiektu czy typu (np. float), tak aby po zmianie wartości zmiennej, na
którą wskazuje, wskaźnik dalej wskazywał na tą zmienną. Uff... trochę
zamieszałem :), mam nadzieję, że wiecie co mam na myśli.
x = 1
y = x
x = 2
x
2
y
1
W pythonie zmienne są właśnie swego rodzaju wskażnikami, w swoim
przykładzie zrobiłeś tak:

przypisałeś do nazwy x obiekt 1
przypisałeś do y to co było przypisane do x czyli 1
przypisałeś do y obiekt 2

jeśli obiekt 1 byłby mutowalnym otrzymałbyś to co chciałeś :)
czyli zmiana obiektu 1 była by widoczna i pod nazwą x i y

Piotr
Rob Wolfe
2007-01-26 14:48:16 UTC
Permalink
Post by kurcze
Z pythonem mam do czynienia od niedawna (jestem początkujący).
Na początek poczytaj trochę o modelu danych Pythona:
http://www.effbot.org/zone/python-objects.htm
http://docs.python.org/ref/objects.html
Post by kurcze
Zastanawia mnie, czy jest sposób żeby utworzyć wskaźnik do danego
obiektu czy typu (np. float), tak aby po zmianie wartości zmiennej, na
którą wskazuje, wskaźnik dalej wskazywał na tą zmienną. Uff... trochę
zamieszałem :), mam nadzieję, że wiecie co mam na myśli.
Nie możesz w Pythonie myśleć kategoriami żywcem wziętymi z C.
W Pythonie zmienna nie jest komórką w pamięci i nie możesz
pobrać jej adresu, co od razu kładzie Twoją koncepcję.
Post by kurcze
x = 1
y = x
x = 2
x
2
y
1
A chcę, żeby y dalej wskazywało na wartość x
Na początek musisz zrozumieć, że w Pythonie typ i wartość
posiadają obiekty, a nie zmienne, które są tylko po to, aby
można się było do obiektów odwołać. Czyli "x = 1" oznacza
"niech x wskazuje na obiekt typu integer o wartości 1",
natomiast "y = x" oznacza "niech y wskazuje na ten sam obiekt
co x".
Lepiej powiedz do czego dążysz, albo pokaż kawałek kodu
w C, który chcesz przetłumaczyć na Pythona, a spróbujemy
coś pomóc.
--
pozdrawiam
Rob
Piotr Dembiński
2007-01-30 12:40:51 UTC
Permalink
"Rob Wolfe" <***@smsnet.pl> writes:

[...]
Post by Rob Wolfe
Nie możesz w Pythonie myśleć kategoriami żywcem wziętymi z C.
Z C nie, ale z Javy często tak.
Rob Wolfe
2007-01-30 13:14:51 UTC
Permalink
Post by Piotr Dembiński
[...]
Post by Rob Wolfe
Nie możesz w Pythonie myśleć kategoriami żywcem wziętymi z C.
Z C nie, ale z Javy często tak.
np.?
Piotr Dembiński
2007-01-31 13:25:57 UTC
Permalink
Post by Piotr Dembiński
[...]
Post by Rob Wolfe
Nie możesz w Pythonie myśleć kategoriami żywcem wziętymi z C.
Z C nie, ale z Javy często tak.
To, że do obiektów są referencje, a nie wskaźniki.
Bart Ogryczak
2007-01-26 16:44:27 UTC
Permalink
Post by kurcze
Z pythonem mam do czynienia od niedawna (jestem początkujący).
Zastanawia mnie, czy jest sposób żeby utworzyć wskaźnik do danego
obiektu czy typu (np. float), tak aby po zmianie wartości zmiennej, na
którą wskazuje, wskaźnik dalej wskazywał na tą zmienną. Uff... trochę
zamieszałem :), mam nadzieję, że wiecie co mam na myśli.
x = 1
y = x
x = 2
x
2
y
1
A chcę, żeby y dalej wskazywało na wartość x
Nie bardzo widze jaki to mialoby miec sens w przypadku typów prostych.
Post by kurcze
x = [1]
y = x
y[0] = 2
x
[2]
Post by kurcze
from copy import copy
z = copy(x)
z[0] = 3
z
[3]
Post by kurcze
x
[2]
Piotr Dembiński
2007-01-30 12:41:41 UTC
Permalink
kurcze <***@gmail.com> writes:

[...]
Post by kurcze
x = 1
y = x
x = 2
x
2
y
1
A chcę, żeby y dalej wskazywało na wartość x
A to nie będą słabe odnośniki (weak references)?
Rob Wolfe
2007-01-30 13:16:31 UTC
Permalink
Post by Piotr Dembiński
[...]
Post by kurcze
x = 1
y = x
x = 2
x
2
y
1
A chcę, żeby y dalej wskazywało na wartość x
A to nie będą słabe odnośniki (weak references)?
Nie rozumiem. Co tu mają do rzeczy słabe odnośniki?
kurcze
2007-01-30 16:41:40 UTC
Permalink
Dziękuję wszystkim za pomoc (szczególnie Tobie Rob za bardzo użyteczne
linki). Myślę, że już to mniej więcej pojmuję. A mianowicie:

Dokonując "przypisania" nie robię nic innego, tylko wprowadzam do
przestrzeni nazw daną nazwę i przypisuję tej nazwie dany obiekt. Przykład:

x = 5

znaczy to, że tworzę "nazwę" x i przypisuję jej obiekt 5, na która ta
nazwa teraz wskazuje.

W pythonie są dwa rodzaje obiektów: "mutable" i "immutable". Wartość
obiektu "mutable" może się zmienić, natomiast wartość obiektu
"immutable" nie może się zmienić. Integer na przykład jest obiektem
"immutable", z czego wynika kilka ciekawych właściwości np.

y = x
(Teraz y wskazuje na ten sam obiekt co x czyli na 5)
x = 3
(Teraz x nie może już wskazywać na obiekt 5, ponieważ wartości obiektu 5
nie można zmienić. x wskazuje teraz na nowo utworzony obiekt 3; y
natomiast w dalszym ciągu wskazuje na obiekt 5)

Dlatego właśnie x = 3, a y = 5

Przejdę teraz do obiektów "mutable". Ich wartość może ulec zmianie.
Takim obiektem jest np. lista czy mapa (nie znam polskiego odpowiednika
wyrazu - może jest właśnie taki :P ). Do listy można dodawać obiekty i
można je usuwać. Jak widzimy określenie "mutable" jest bardzo trafne ;).
Zobaczmy:

a = [ 1, 2, 3 ]
b = a
(b wskazuje na ten sam obiekt co a, czyli na listę)
a.append( 4 )
(do a dodajemy obiekt 4)

Co się dzieje z b? b dalej wskazuje na ten sam obiekt co a! Ta sytuacja
ma miejsce ponieważ listę można zmienić i dodać do niej obiekt 4. Nie
musi już być tworzony nowy obiekt bo stary jest całkiem OK :).
A co jeśli potrzebujemy kopię listy a? Oczywiście po to jest "slicing":
b = a[:]

Wracając do mojego problemu...
Mam pewną rozbudowaną mapę i potrzebuję przekazać pewne elementy do
funkcji aby zmienić te elementy.
Przychodzą mi na myśl dwa rozwiązania: aby przekazać do funkcji
"referencję" do danego elementu mapy można:
1) przekazać do tej funkcji nazwę mapy i listę kluczy (lub najbardziej
zagłębiony element będący jeszcze listą lub mapą i klucz); następnie
utworzyć jakąś mała funkcję, która mając te dane zwróci odpowiedni obiekt
2) utworzyć funkcję "w biegu" (lambda), która zwróci nam odpowiedni
obiekt i ją przekazać do naszej głównej funkcji

Mam nadzieję, że moje rozumowanie jest poprawne. Jeśli nie jest lub
znacie lepsze sposoby na osiągnięcie tego samego efektu, proszę o
poprawienie mnie.
Pozdrawiam, kurcze
Bart Ogryczak
2007-01-30 19:55:38 UTC
Permalink
Post by kurcze
b = a[:]
Bynajmniej. Slicing sluzy do "krojenia" list na kawalki. Do kopiowania
sluzy modul copy z funkcjami copy() i deepcopy(), które to dzialaja
nie tylko z listami, ale tez tez ze slownikami i dowolnymi obiektami,
które maja zdefinowane metody __copy__ i __deepcopy__
http://docs.python.org/lib/module-copy.html
Rob Wolfe
2007-01-30 21:05:37 UTC
Permalink
Post by Bart Ogryczak
Post by kurcze
b = a[:]
Bynajmniej. Slicing sluzy do "krojenia" list na kawalki. Do kopiowania
Ależ to jest powszechny idiom do _płytkiego_ kopiowania list,
chociaż ja preferuję:
b = list(a)
Post by Bart Ogryczak
sluzy modul copy z funkcjami copy() i deepcopy(), które to dzialaja
nie tylko z listami, ale tez tez ze slownikami i dowolnymi obiektami,
które maja zdefinowane metody __copy__ i __deepcopy__
http://docs.python.org/lib/module-copy.html
Zaletą tego modułu jest większa ogólność, ale powyższa metoda
do _płytkiego_ kopiowania listy w zupełności wystarczy.
--
pozdrawiam
Rob
Bart Ogryczak
2007-01-31 10:07:58 UTC
Permalink
Post by Rob Wolfe
Post by Bart Ogryczak
Post by kurcze
b = a[:]
Bynajmniej. Slicing sluzy do "krojenia" list na kawalki. Do kopiowania
Ależ to jest powszechny idiom do _płytkiego_ kopiowania list,
Niemniej mówienie, ze krojenie sluzy do kopiowania, to jednak
przesada.
Post by Rob Wolfe
b = list(a)
Na jedno wychodzi.
Post by Rob Wolfe
Post by Bart Ogryczak
sluzy modul copy z funkcjami copy() i deepcopy(), które to dzialaja
nie tylko z listami, ale tez tez ze slownikami i dowolnymi obiektami,
które maja zdefinowane metody __copy__ i __deepcopy__
http://docs.python.org/lib/module-copy.html
Zaletą tego modułu jest większa ogólność, ale powyższa metoda
do _płytkiego_ kopiowania listy w zupełności wystarczy.
Problem w tym, ze dziala tylko i wylacznie dla list, nie krotek,
zbiorów, slowników itd. Jesli uzyjesz copy() i dojdziesz do wniosku
np. ze jednak zmienna powinna byc zbiorem, a nie lista, to kodu
zmieniac nie musisz. No, ale to w zasadzie kwestia gustu i tego co sie
robi. W moim kodzie mam duzo zonglowania typami, mapowania miedzy
slownikami, listami itd. Wiec uzywam copy.
Rob Wolfe
2007-01-30 21:02:59 UTC
Permalink
kurcze <***@gmail.com> writes:

[...]
Post by kurcze
b = a[:]
To jest OK, ale ja wolę coś bardziej czytelnego:
b = list(a) # utworz nowa liste na podstawie istniejacej
Post by kurcze
Wracając do mojego problemu...
Mam pewną rozbudowaną mapę i potrzebuję przekazać pewne elementy do
BTW zwykle używamy nazwy "słownik", a nie "mapa".
Post by kurcze
funkcji aby zmienić te elementy.
Przychodzą mi na myśl dwa rozwiązania: aby przekazać do funkcji
1) przekazać do tej funkcji nazwę mapy i listę kluczy (lub najbardziej
zagłębiony element będący jeszcze listą lub mapą i klucz); następnie
utworzyć jakąś mała funkcję, która mając te dane zwróci odpowiedni obiekt
2) utworzyć funkcję "w biegu" (lambda), która zwróci nam odpowiedni
obiekt i ją przekazać do naszej głównej funkcji
Mam nadzieję, że moje rozumowanie jest poprawne. Jeśli nie jest lub
znacie lepsze sposoby na osiągnięcie tego samego efektu, proszę o
poprawienie mnie.
Generalnie rozumujesz dobrze, ale żeby coś więcej powiedzieć,
to trzebaby zobaczyć jakiś konkretny przypadek użycia.

P.S.
A tak na marginesie to Twój tekst odnośnie typów i przypisań
jest niezły. IMHO spokojnie móglbyś to dorzucić gdzieś do wiki
grupy (http://python.kofeina.net). Ten temat powraca jak bumerang.
--
pozdrawiam
Rob
kurcze
2007-01-31 17:51:25 UTC
Permalink
Post by Rob Wolfe
P.S.
A tak na marginesie to Twój tekst odnośnie typów i przypisań
jest niezły. IMHO spokojnie móglbyś to dorzucić gdzieś do wiki
grupy (http://python.kofeina.net). Ten temat powraca jak bumerang.
Jeśli ktoś jest zainteresowany to zachęcam od utworzenia jakiegoś
rzetelnego tekstu wyjaśniającego problem na podstawie moich wypocin (nie
trzeba podawać mnie jako współautora). W obecnej postaci raczej nie
nadaje się na upublicznienie :). Zgadzam się też, że zdecydowanie
przesadziłem pisząc, że slicing jest po to, żeby kopiować listę. Jest po
prostu w tym pomocny... Swoją drogą szkoda, że w pythonie nie ma jakiejś
struktury podobnej do wskaźnika. Skoro funkcja id() zwraca unikalny
identyfikator obiektu
(file://localhost/usr/share/doc/python/html/lib/built-in-funcs.html#l2h-37),
to nie byłoby to chyba takie trudne w implementacji... Wystarczyłaby
funkcja, która zwracałaby obiekt na podstawie przekazanego id. To
ułatwiłoby pracę komuś kto przenosi się z języka C.

Pozdrawiam, kurcze
kurcze
2007-01-31 17:54:21 UTC
Permalink
Ooops... link odnosi się do localhosta :)
Poprawny: http://docs.python.org/lib/built-in-funcs.html#l2h-39
Rob Wolfe
2007-01-31 19:34:36 UTC
Permalink
Post by kurcze
Swoją drogą szkoda, że w pythonie nie ma
jakiejś struktury podobnej do wskaźnika. Skoro funkcja id() zwraca
unikalny identyfikator obiektu
(file://localhost/usr/share/doc/python/html/lib/built-in-funcs.html#l2h-37),
to nie byłoby to chyba takie trudne w implementacji... Wystarczyłaby
funkcja, która zwracałaby obiekt na podstawie przekazanego id. To
ułatwiłoby pracę komuś kto przenosi się z języka C.
Przecież wszystkie zmienne w Pythonie są w pewnym sensie
wskaźnikami do obiektów.
Nie rozumiem w czym miałaby pomóc funkcja zwracająca obiekt na podstawie id?
Po drugie jedną z zalet Pythona jest to, że nie jest to C. :)
--
pozdrawiam
Rob
kurcze
2007-01-31 20:58:24 UTC
Permalink
Post by Rob Wolfe
Post by kurcze
Swoją drogą szkoda, że w pythonie nie ma
jakiejś struktury podobnej do wskaźnika. Skoro funkcja id() zwraca
unikalny identyfikator obiektu
(file://localhost/usr/share/doc/python/html/lib/built-in-funcs.html#l2h-37),
to nie byłoby to chyba takie trudne w implementacji... Wystarczyłaby
funkcja, która zwracałaby obiekt na podstawie przekazanego id. To
ułatwiłoby pracę komuś kto przenosi się z języka C.
Przecież wszystkie zmienne w Pythonie są w pewnym sensie
wskaźnikami do obiektów.
Nie rozumiem w czym miałaby pomóc funkcja zwracająca obiekt na podstawie id?
Po drugie jedną z zalet Pythona jest to, że nie jest to C. :)
Masz rację :]. Jednak trochę trudno mi przestawić swój sposób myślenia.
Znowu mamy tu przecież do czynienia z podziałem na "mutable" i
"immutable". Jeśli zrobię:
x = 5
x_id = id(x)
to x_id to będzie identyfikator niemutowalnego obiektu "5" a nie zmiennej x
dlatego:
y = x
x = 3
y_id = id(y)

teraz x_id == y_id, a id(x) da nam inną wartość. Cóż... widocznie muszę
się pożegnać ze wskaźnikami ;> ...

Pozdrawiam, kurcze
Piotr Dembiński
2007-02-01 14:11:37 UTC
Permalink
Rob Wolfe <***@smsnet.pl> writes:

[...]
Przecież wszystkie zmienne w Pythonie są w pewnym sensie wskaźnikami
do obiektów.
Odnośnikami.

Piotr Dembiński
2007-02-01 14:01:49 UTC
Permalink
kurcze <***@gmail.com> writes:

[...]
funkcja id() zwraca unikalny identyfikator obiektu
Identyfikator jest unikalny w dowolnym momencie przetwarzania, ale nie
unikalny w ramach całej sesji.
Jaroslaw Zabiello
2007-01-31 16:11:24 UTC
Permalink
Post by kurcze
Dokonując "przypisania" nie robię nic innego, tylko wprowadzam do
x = 5
znaczy to, że tworzę "nazwę" x i przypisuję jej obiekt 5, na która ta
nazwa teraz wskazuje.
W pythonie są dwa rodzaje obiektów: "mutable" i "immutable". Wartość
obiektu "mutable" może się zmienić, natomiast wartość obiektu
"immutable" nie może się zmienić. Integer na przykład jest obiektem
"immutable", z czego wynika kilka ciekawych właściwości np.
y = x
(Teraz y wskazuje na ten sam obiekt co x czyli na 5)
x = 3
(Teraz x nie może już wskazywać na obiekt 5, ponieważ wartości obiektu 5
nie można zmienić. x wskazuje teraz na nowo utworzony obiekt 3; y
natomiast w dalszym ciągu wskazuje na obiekt 5)
Dlatego właśnie x = 3, a y = 5
Przejdę teraz do obiektów "mutable". Ich wartość może ulec zmianie.
Takim obiektem jest np. lista czy mapa (nie znam polskiego odpowiednika
wyrazu - może jest właśnie taki :P ). Do listy można dodawać obiekty i
można je usuwać. Jak widzimy określenie "mutable" jest bardzo trafne ;).
a = [ 1, 2, 3 ]
b = a
(b wskazuje na ten sam obiekt co a, czyli na listę)
a.append( 4 )
(do a dodajemy obiekt 4)
Co się dzieje z b? b dalej wskazuje na ten sam obiekt co a! Ta sytuacja
ma miejsce ponieważ listę można zmienić i dodać do niej obiekt 4. Nie
musi już być tworzony nowy obiekt bo stary jest całkiem OK :).
Bardzo interesująco to opisałeś. Zastanawiam się czy aby to faktycznie
wynika z tego podziału na obiekty mutowalne i niemutowalne. Np. w Ruby mam
identyczną sytuację, a tam raczej nie ma takiego podziału...

x = 3
y = x
x = 5
p y # => 3
--
Jarosław Zabiełło
http://blog.zabiello.com
Piotr Dembiński
2007-01-31 13:34:40 UTC
Permalink
Post by Rob Wolfe
Post by Piotr Dembiński
[...]
Post by kurcze
x = 1
y = x
x = 2
x
2
y
1
A chcę, żeby y dalej wskazywało na wartość x
A to nie będą słabe odnośniki (weak references)?
Nie rozumiem. Co tu mają do rzeczy słabe odnośniki?
Nic.
Piotr Dembiński
2007-01-31 13:42:46 UTC
Permalink
Post by Rob Wolfe
Post by Piotr Dembiński
[...]
Post by kurcze
x = 1
y = x
x = 2
x
2
y
1
A chcę, żeby y dalej wskazywało na wartość x
A to nie będą słabe odnośniki (weak references)?
Nie rozumiem. Co tu mają do rzeczy słabe odnośniki?
Nic.
Nic, ale już wiem, o co chodziło kurcze'owi: o zmienne pośredniczące,
które są przezroczyste dla operacji przypisania.
Piotr Dembiński
2007-01-31 13:52:17 UTC
Permalink
Post by Piotr Dembiński
Post by Rob Wolfe
Post by Piotr Dembiński
[...]
Post by kurcze
x = 1
y = x
x = 2
x
2
y
1
A chcę, żeby y dalej wskazywało na wartość x
A to nie będą słabe odnośniki (weak references)?
Nie rozumiem. Co tu mają do rzeczy słabe odnośniki?
Nic.
Nic, ale już wiem, o co chodziło kurcze'owi: o zmienne
pośredniczące, które są przezroczyste dla operacji przypisania.
...innymi słowy o makra. Składnia mogłaby być następująca:

x = 1
def y x
x = 2
Rob Wolfe
2007-01-31 13:42:00 UTC
Permalink
Post by Piotr Dembiński
Post by Rob Wolfe
Post by Piotr Dembiński
[...]
Post by kurcze
x = 1
y = x
x = 2
x
2
y
1
A chcę, żeby y dalej wskazywało na wartość x
A to nie będą słabe odnośniki (weak references)?
Nie rozumiem. Co tu mają do rzeczy słabe odnośniki?
Nic.
Nic, ale już wiem, o co chodziło kurcze'owi: o zmienne pośredniczące,
które są przezroczyste dla operacji przypisania.
Zakładam się o browar, że OP nic takiego nie miał na myśli. :)

--
pozdrawiam
Rob
Piotr Dembiński
2007-02-01 14:00:53 UTC
Permalink
Post by Rob Wolfe
Post by Piotr Dembiński
Post by Rob Wolfe
Post by Piotr Dembiński
[...]
Post by kurcze
x = 1
y = x
x = 2
x
2
y
1
A chcę, żeby y dalej wskazywało na wartość x
A to nie będą słabe odnośniki (weak references)?
Nie rozumiem. Co tu mają do rzeczy słabe odnośniki?
Nic.
Nic, ale już wiem, o co chodziło kurcze'owi: o zmienne
pośredniczące, które są przezroczyste dla operacji przypisania.
Zakładam się o browar, że OP nic takiego nie miał na myśli. :)
To wynika z podanego przykładu.
Loading...