2009-09-29 10 views
5

Wysłałem referencję do obiektu bool i zmodyfikowałem go w ramach metody. Po zakończeniu wykonywania metody wartość logu poza metodą pozostała niezmieniona.Czy bool Pythona jest przekazywany według wartości?

To prowadzi mnie do przekonania, że ​​bool Pythona są przekazywane przez wartość. Czy to prawda? Jakie inne typy Pythona zachowują się w ten sposób?

+0

Duplikat, zobacz http://stackoverflow.com/questions/534375/passing-values-in-python –

Odpowiedz

12

Zmienne języka Python nie są "odniesieniami" w rozumieniu C++. Raczej są po prostu lokalnymi nazwami związanymi z obiektem w jakiejś arbitralnej lokalizacji w pamięci. Jeśli ten obiekt sam się zmienia, zmiany w nim będą widoczne w innych zakresach, które związały nazwę z obiektem. Wiele typów pierwotnych (w tym bool, int, str i) jest jednak niezmiennych. Nie możesz zmienić ich wartości w miejscu; zamiast tego przypisujesz nową wartość tej samej nazwie w swoim zasięgu lokalnym.

W rzeczywistości, prawie za każdym razem * widać kod formularza foo = X, oznacza to, że nazwa foo jest przypisane nową wartość (X) w swojej lokalnej przestrzeni nazw, a nie, że lokalizacja w pamięci nazwany przez foo jest po zaktualizowaniu wewnętrznego wskaźnika, aby odnieść się do lokalizacji X.

* - Jedynym wyjątkiem od tego w Pythonie są metody setera dla właściwości, które mogą pozwolić Ci napisać obj.foo = X i mieć to przepisane w tle, aby zamiast tego wywołać metodę taką jak obj.setFoo(X).

+0

Tak, ściśle mówiąc WSZYSTKO w Pythonie jest przekazywane przez adres. Python ma tylko jeden proces przekazywania argumentów. To tylko fakt, że niektóre obiekty są zmienne, a inne nie dają złudzenia, że ​​coś jest bardziej skomplikowane. –

1

To zależy od tego, czy obiekt jest zmienny czy niezmienny. Niezmienne obiekty zachowują się tak, jakbyś widział je za pomocą bool, podczas gdy zmieniające się obiekty zmieniają się.

dokumencie: http://www.testingreflections.com/node/view/5126

Pythona przechodzi, referencje do obiektów o wartość (jak Java), a wszystko w Pythonie jest obiektem. To brzmi prosto, ale potem zauważysz, że niektóre typy danych zdają się wykazywać cechy pass-by-value, podczas gdy inne wydają się działać jak referencje ... o co chodzi?

Ważne jest, aby zrozumieć zmienne i niezmienne obiekty. Niektóre obiekty, takie jak łańcuchy, krotki i liczby, są niezmienne. Zmiana ich w funkcji/metodzie spowoduje utworzenie nowej instancji, a oryginalna instancja poza funkcją/metodą nie zostanie zmieniona. Inne obiekty, takie jak listy i słowniki, są zmienne, co oznacza, że ​​możesz zmienić obiekt w miejscu. Dlatego też zmiana obiektu wewnątrz funkcji/metody spowoduje również zmianę oryginalnego obiektu na zewnątrz.

+0

-1: Po pierwsze, wydaje się, że jest to kopia zaakceptowanej odpowiedzi na wspomniane duplikaty pytania (które mogą być przypadkowo).Po drugie, po prostu nie możesz zmienić niezmiennych obiektów - to znaczy, co niezmienne oznacza. Mówienie, że zmiana niezmiennych obiektów tworzy nową instancję, po prostu mylą problem. Możesz ponownie powiązać nazwę obiektu niezmiennego, ale to nie to samo! –

+0

Interesujące, nie widziałem nawet duplikatu. To pytanie nie było oznaczone jako duplikat, gdy odpowiadałem. Googling "Python pass by reference" dał mi powyższy link. Również przypadek, z którym masz problem, jest akceptowaną odpowiedzią przez duplikat. Nie jest mi trudno zrozumieć, że jeśli Python będzie mógł edytować, to zrobi to, a jeśli nie, to utworzy kopię lokalną. Oto inna strona, która cytuje powyższy link, ale zawiera dodatkowe wyjaśnienia: http://bogdan.org.ua/2008/02/11/python-passing-by-value-vs-passing-by-reference.html – FModa3

0

W skrócie, nie ma zmiennych w Pythonie; są przedmioty (jak prawda i fałsz, boole są niezmienne) i imiona. Nazwy to tak zwane zmienne, ale nazwy należą do zakresu, zazwyczaj nie można zmienić nazw innych niż lokalne.

+1

"Nie ma żadnych zmiennych w Pythonie" jest pedantyczny i wprowadzający w błąd, naprawdę chciałbym, żeby ludzie przestali to mówić. –

1

Należy pamiętać, że w języku Python istnieje nr dla funkcji lub metody ponownego wiązania nazwy w wywołującej przestrzeni nazw. Kiedy piszesz "Wysłałem referencję do obiektu bool i zmodyfikowałem go w ramach metody", to co faktycznie zrobiłeś (jak się domyślam) było ponowne powiązanie nazwy parametru (do którego wartość bool była związana przez wywołanie) wewnątrz ciało metody.