ubuntuusers.de

[Python 2.x] Call-By-Reference

Status: Gelöst | Ubuntu-Version: Ubuntu 9.10 (Karmic Koala)
Antworten |

Glocke

Avatar von Glocke

Anmeldungsdatum:
1. März 2009

Beiträge: 880

Wohnort: Thüringen

Hi,

in div. Literatur habe ich gelesen, dass die Parameter bei Funktionsaufrufen in Python stets per Call-By-Reference übergeben werden. Warum funktioniert das hier dann nicht?

1
2
3
4
5
6
def foo(bar):
	bar = bar + 1

i = 10
foo(i)
print i

da kommt 10 raus, anstatt der 11 mit der ich gerechnet habe. Kann mir das jmd. erklären? Bei google usw. finde ich nur weitere Bestätigungen für die oben genannte Erkenntnis -.-

Barabbas

Avatar von Barabbas

Anmeldungsdatum:
31. März 2007

Beiträge: 1651

Wohnort: Münster

Das ist bei Int, Float, Tuplen und Strings so. Über die Interna des Python-Datenmodells weiß ich leider nicht bescheid, so dass ich dir da keine Erklärung geben kann. Aber immerhin weißt du jetzt, dass es kein Fehler ist 😉

//edit:
Ok, das Stichtwort lautet "immutable objects" bzw. "unveränderliche Objekte". Kurz: Die oben genannten Objekte sind grundsätzlich unveränderlich, werden sie manipuliert wird jeweils ein neues Objekt vom selben Typen erstellt.

Vgl. dazu: http://www.testingreflections.com/node/view/5126
und sogar: http://de.wikipedia.org/wiki/Python_(Programmiersprache)

Glocke

(Themenstarter)
Avatar von Glocke

Anmeldungsdatum:
1. März 2009

Beiträge: 880

Wohnort: Thüringen

hmmm das klingt alles nicht sehr gut. welche möglichkeit bleibt mir dann, eine objekt-instanz als referenz zu übergeben: der gute alte Zeiger?

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4675

Wohnort: Berlin

@Barabbas: Die Objekte werden ja gar nicht manipuliert, sie sind ja unveränderlich. Und es wird auch gar keine Manipulation versucht, in der Funktion wird nur der Name neu gebunden.

@Glocke: Der gute alte Zeiger ist bei modernen Sprachen wie Python oder auch Java und C# (managed code) nicht mehr für den Programmierer zugänglich. Er wird allerdings hinter den Kulissen immer übergeben. So auch in Deinem Beispiel. Da wird die Referenz auf eine 10 übergeben und an den lokalen Namen bar gebunden. Und in der Funktion wird dieser Name dann an ein anderes Objekt gebunden – eine 11. Diese Bindung hat allerdings keine Auswirkung auf die Bindung von dem i an die 10 auf Modulebene.

Glocke

(Themenstarter)
Avatar von Glocke

Anmeldungsdatum:
1. März 2009

Beiträge: 880

Wohnort: Thüringen

und wie realisiere ich nun den call by reference damit meine 11 auch aus der funktion rauskommt?

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4675

Wohnort: Berlin

@Glocke: Mit return!?

Glocke

(Themenstarter)
Avatar von Glocke

Anmeldungsdatum:
1. März 2009

Beiträge: 880

Wohnort: Thüringen

Marc 'BlackJack' Rintsch schrieb:

@Glocke: Mit return!?

& bei 2 oder mehr objekten?! (sag jetzt nicht return an array xD)

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4675

Wohnort: Berlin

Nein eher ein Tupel. Oder jedes andere beliebige iterierbare Objekt. Und bei der Zuweisung des Ergebnisses dann "sequenz unpacking" verwenden:

1
2
3
4
5
6
def add_mul(a, b):
    return a + b, a * b

x, y = add_mul(23, 42)
print x  # 65
print y  # 966

Wobei man sich die Frage stellen sollte warum eine Funktion mehrere Ergebnisse hat. Allzu oft sollte das nicht vorkommen, oder man sollte vielleicht den Entwurf noch einmal überdenken. In Java hat man diese syntaktische Möglichkeit zum Beispiel nicht, da würde man eine eigene Klasse für den Rückgabetyp brauchen.

Glocke

(Themenstarter)
Avatar von Glocke

Anmeldungsdatum:
1. März 2009

Beiträge: 880

Wohnort: Thüringen

also in meinem fall

1
2
3
4
5
6
def foo(bar):
	return bar + 1

i = 10
i = foo(i)
print i

funzt. naja ich dachte da gibts ne andere möglichkeit aber so geht auch.... 😀

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Glocke schrieb:

also in meinem fall

1
2
3
4
5
6
def foo(bar):
	return bar + 1

i = 10
i = foo(i)
print i

funzt. naja ich dachte da gibts ne andere möglichkeit aber so geht auch.... 😀

Wo sind hier mehrere Rückgabewerte notwendig?

Glocke

(Themenstarter)
Avatar von Glocke

Anmeldungsdatum:
1. März 2009

Beiträge: 880

Wohnort: Thüringen

nirgendwo, hab ich ja nicht behauptet. die frage war lediglich was bei mehreren wäre & das wurde beantwortet.

Antworten |