Python: kiedy zmienna jest przekazywana przez referencję, a kiedy przez wartość? [duplikat]
Możliwy duplikat:
Python: jak przekazać zmienną przez odniesienie?
Mój kod:
locs = [ [1], [2] ]
for loc in locs:
loc = []
print locs
# prints => [ [1], [2] ]
Dlaczego loc
nie odnosi się do elementów locs
?
Python: wszystko jest przekazywane jako odniesienie, chyba że jest wyraźnie skopiowane [czy to nie prawda ? ]
Proszę wyjaśnić.. w jaki sposób python decyduje o odwołaniu się i kopiowaniu ?Update:
Jak to zrobić ?def compute(ob):
if isinstance(ob,list): return process_list(ob)
if isinstance(ob,dict): return process_dict(ob)
for loc in locs:
loc = compute(loc) # What to change here to make loc a reference of actual locs iteration ?
- locs musi zawierać ostateczną przetworzoną odpowiedź !
- nie chcę używać
enumerate
, czy jest to możliwe bez niego ?
6 answers
Wszystko w Pythonie jest przekazywane i przypisywane przez wartość, tak samo jak wszystko jest przekazywane i przypisywane przez wartość w Javie. Każda wartość w Pythonie jest odniesieniem (wskaźnikiem) do obiektu. Obiekty nie mogą być wartościami. Assignment zawsze kopiuje wartość (która jest wskaźnikiem); dwa takie wskaźniki mogą zatem wskazywać na ten sam obiekt. Obiekty nigdy nie są kopiowane, chyba że robisz coś jawnego, aby je skopiować.
W Twoim przypadku każda iteracja pętli przypisuje element listy do zmienna loc
. Następnie przypisujesz coś innego do zmiennej loc
. Wszystkie te wartości są wskaźnikami; przypisujesz wskaźniki; ale nie wpływasz w żaden sposób na żadne obiekty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-14 19:39:15
Effbot (znany jako Fredrik Lundh) opisał zmienny styl przekazywania Pythona jako wywołanie przez obiekt: http://effbot.org/zone/call-by-object.htm
Obiekty są przydzielane na stercie i wskaźniki do nich mogą być przekazywane w dowolnym miejscu.
- kiedy wykonujesz przypisanie, takie jak
x = 1000
, tworzony jest wpis słownikowy, który mapuje łańcuch " x " w bieżącej przestrzeni nazw na wskaźnik do obiektu integer zawierającego tysiąc. - po aktualizacji "x" z
x = 2000
, tworzony jest nowy obiekt integer i słownik jest aktualizowany tak, aby wskazywał na nowy obiekt. Stary obiekt tysiąc jest niezmieniony (i może, ale nie musi być żywy, w zależności od tego, czy cokolwiek innego odnosi się do obiektu). - kiedy wykonujesz nowe przypisanie, takie jak
y = x
, tworzony jest nowy wpis słownikowy "y", który wskazuje na ten sam obiekt, co wpis dla"x". - obiekty takie jak łańcuchy i liczby całkowite są niezmienne . Oznacza to po prostu, że nie ma metod, które może zmieniać obiekt po jego wytworzeniu. Na przykład, po utworzeniu obiektu integer one-thousand, nigdy się nie zmieni. Matematyka jest wykonywana przez tworzenie nowych obiektów całkowitych.
- obiekty takie jak listy są mutowalne . Oznacza to, że zawartość obiektu może być zmieniana przez cokolwiek wskazującego na obiekt. Na przykład,
x = []; y = x; x.append(10); print y
wydrukuje[10]
. Pusta lista została utworzona. Zarówno "x", jak i " y " wskazują na tę samą listę. Metoda append mutuje (aktualizuje) listę obiekt (jak dodanie rekordu do bazy danych) i wynik jest widoczny zarówno dla "x" jak i " y " (tak jak aktualizacja bazy danych byłaby widoczna dla każdego połączenia z tą bazą danych).
Mam nadzieję, że to wyjaśni ci problem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-02 20:59:26
W Pythonie nie pomaga myślenie w kategoriach odniesień lub wartości. Ani nie jest poprawne.
W Pythonie zmienne są tylko nazwami. W pętli for, {[1] } jest tylko nazwą wskazującą na bieżący element na liście. Wykonując loc = []
po prostu rebinduje nazwę loc
do innej listy, pozostawiając tylko oryginalną wersję.
Ale ponieważ w twoim przykładzie każdy element jest listą, możesz w rzeczywistości zmutować Ten element, a to będzie odzwierciedlone w oryginale lista:
for loc in locs:
loc[0] = loc[0] * 2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-14 05:42:13
Kiedy mówisz
loc = []
Zmieniasz zmienną loc
na nowo utworzoną pustą listę
Być może chcesz
loc[:] = []
Który przypisuje wycinek (który jest całą listą) loc do pustej listy
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-14 05:40:29
Wszystko jest przekazywane przez obiekt. Rebinding i mutacja to różne operacje.
locs = [ [1], [2] ]
for loc in locs:
del loc[:]
print locs
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-14 05:39:45
Dlaczego loc nie jest odniesieniem do elementów locs ?
Jest . A przynajmniej jest w tym samym sensie, co każda inna zmienna w Pythonie. Zmienne Pythona są nazwami , a nie storage . {[1] } jest nazwą, która odnosi się do elementów [[1,2], [3,4]]
, podczas gdy {[3] } jest nazwą, która odnosi się do całej struktury.
loc = []
To nie oznacza "spójrz na to, co loc
nazywa i powoduje, że zmienia się w []
". It cannot oznacza to, że obiekty Pythona nie są zdolne do tego typu rzeczy.
Zamiast tego oznacza " ponieważ loc
przestaje być nazwą dla rzeczy, dla której jest obecnie nazwą, i zaczyna być nazwą dla []
". (Oczywiście, oznacza to konkretny []
, który jest tam dostarczany, ponieważ ogólnie może być kilka obiektów w pamięci, które są takie same.)
Oczywiście zawartość locs
nie ulega zmianie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-14 07:14:34