Re: [Python-de] Parameter in Python
Am 12.11.2013 09:58, schrieb Stefan Schwarzer:
Im zweiten Fall wird durch die Slice-Zuweisung das übergebene Listen-Objekt selbst ("in-place") verändert, so dass diese Änderungen auch nach Verlassen der Funktion sichtbar sind. Anstelle der Slice-Zuweisung könnte jede andere Anweisung stehen, die die Liste verändert, zum Beispiel `list_.append(1)` oder `list_.pop()`.
Ja, das habe ich schon verstanden nur ist folgendes nicht "call-by-value" like: def unchanged(list_): list2_ = list_ list2_.pop(0) L = [1, 2, 3] unchanged(L) print L Es geht um die Semantik. Ich halte die Aussage, das sei call-by-value schlicht für falsch. Man kann sich darauf einigen, dass Python es anders macht und es meinteswegen call-by-assign nennen. Ungewohnt ist es trotzdem.
Wie gesagt, es gibt _keine_ unterschiedliche Parameter-Übergabe für veränderliche und unveränderliche Objekte. Entscheidend ist, was du mit den Objekten innerhalb deiner Funktion/Methode machst.
Ich würde sagen die Objekte unterscheiden sich in ihrem Verhalten. Und ja, das halte ich für ein Problem weil es unerwünschte Seiteneffekte produziert. Solange man ein Bewusstsein für schafft, ist es ok.
Am 12.11.2013 um 14:51 schrieb Alexander Langer:
Ich würde sagen die Objekte unterscheiden sich in ihrem Verhalten.
Natürlich. Nur hat das nichts mit der Art der Übergabe zu tun. Es gibt mutable und immutable Objekte. Diese unterscheiden sich genau bzgl. dieser Eigenschaft. Da das auch an anderer Stelle wichtig ist, steht das in der Standardbibliothek quasi an jedem Objekte dran. Von Überraschungen kann in meinen Augen also eigentlich keine Rede sein.
Und ja, das halte ich für ein Problem weil es unerwünschte Seiteneffekte produziert.
Welche denn z.B.? Python zeichnet sich gegenüber anderen Sprachen eigentlich dadurch aus, daß es extrem konsistent und "überraschungslos" ist. Bezogen auf die Parameterübergabe: So lange du einen übergebenen Wert in eine Funktion nicht änderst, ist's eh alles ok. Wenn du ihn ändern willst, mußt du wissen, ob er mutable ist oder nicht. Wenn ja, kannst du ihn ändern. Wenn nicht nicht. Das war's eigentlich.
Solange man ein Bewusstsein für schafft, ist es ok.
Die Unterscheidung von mutable und immutable ist in der Pythonwelt in meinen Augen ständig präsent. Von daher ist's für mich schwer nachzuvollziehen, wie man da kein Bewußtsein dafür haben kann. Persönlich hallte ich diese call-by-xyz Diskussion für eine typisch akademische Haarspalterei, die zu C-Zeiten mal Sinn gemacht hat. Aber wer C programmieren will, soll doch bitte C programmieren. In Python geht es um Objekte und Variablen sind Referenzen auf diese Objekte. Was an eine Funktion übergeben wird, ist die Referenz. Ich kann jetzt also sagen, daß das Objekt "by reference" übergeben wird, oder aber die Referenz "by value". Nur bringt das niemandem neue Erkenntnisse. Vielleicht hilft übrigen http://pythontutor.com/ zu verstehen, wie Python funktioniert. Grüße, Achim
On 12.11.2013 15:13, Achim Domma wrote:
Referenzen auf diese Objekte
Ich störe mich extrem an dem Begriff Referenzen. Eine Variable in Python speichert ein PyObject*, also einen Pointer. Und entweder ich überschreibe den Pointer mit was neuem (ohne das alte zu verändern), oder ich verändere das, worauf der Pointer zeigt, ohne ihn zu überschreiben. Ob das jetzt "call by reference" oder "call by value" oder "call by assignment" oder "call by object" oder was ganz anderes ist... Michael -- Öffentlicher Schlüssel: 48F81543 - Michael Ziegler (Svedrin) Wo kämen wir denn da hin, wenn jeder nur fragte "Wo kämen wir denn da hin?", aber niemand ginge, um zu sehen, wohin wir kämen, wenn wir gingen? (Kurt Marti)
Hi Alexander, On 2013-11-12 14:51, Alexander Langer wrote:
Am 12.11.2013 09:58, schrieb Stefan Schwarzer:
Im zweiten Fall wird durch die Slice-Zuweisung das übergebene Listen-Objekt selbst ("in-place") verändert, so dass diese Änderungen auch nach Verlassen der Funktion sichtbar sind. Anstelle der Slice-Zuweisung könnte jede andere Anweisung stehen, die die Liste verändert, zum Beispiel `list_.append(1)` oder `list_.pop()`.
Ja, das habe ich schon verstanden nur ist folgendes nicht "call-by-value" like:
def unchanged(list_): list2_ = list_ list2_.pop(0)
L = [1, 2, 3] unchanged(L) print L
ich halte es in der Tat nicht für glücklich, die Parameter-Übergabe in Python "call by value" zu nennen. Das führt genau so zu Missverständnissen, wie es "call by reference" zu nennen. In der "Ausbildung" werden üblicherweise vielleicht nur "call by value" und "call by reference" erklärt. Bei vielen Menschen scheint das zu der Annahme zu führen, es gäbe nichts anderes. :-)
Es geht um die Semantik. Ich halte die Aussage, das sei call-by-value schlicht für falsch.
Ich auch. Oder zumindest derart missverständlich, dass man die Semantik am besten nicht als "call by value" bezeichnen sollte.
Man kann sich darauf einigen, dass Python es anders macht und es meinteswegen call-by-assign nennen. Ungewohnt ist es trotzdem.
Wenn man vorher nur "call by value" und "call by reference" kannte, sicherlich. Ich fand es anfangs auch etwas ungewohnt.
Wie gesagt, es gibt _keine_ unterschiedliche Parameter-Übergabe für veränderliche und unveränderliche Objekte. Entscheidend ist, was du mit den Objekten innerhalb deiner Funktion/Methode machst.
Ich würde sagen die Objekte unterscheiden sich in ihrem Verhalten.
Ja (aber die Parameter-Übergabe funktioniert gleich).
Und ja, das halte ich für ein Problem weil es unerwünschte Seiteneffekte produziert.
Das kommt auf deinen Code an. Oft handelt es sich ja um _gewünschte_ Seiteneffekte. Das Musterbeispiel ist der Aufruf einer Methode mit `self` als erstem Parameter, der dann dazu verwendet kann, die Attribute des Objekts zu ändern, also das Objekt "in-place" zu verändern.
Solange man ein Bewusstsein für schafft, ist es ok.
Das denke ich auch. Ich habe mal einen Vortrag gehalten, der unter anderem auch auf Zuweisungs-Semantik und Parameter-Übergabe in Python eingeht: http://sschwarzer.com/download/robustere_python_programme_clt2010_print.pdf Viele Grüße Stefan
Hallöchen! Alexander Langer schreibt:
[...]
Es geht um die Semantik. Ich halte die Aussage, das sei call-by-value schlicht für falsch. Man kann sich darauf einigen, dass Python es anders macht und es meinteswegen call-by-assign nennen. Ungewohnt ist es trotzdem.
Jeder muß das anders in seinen Kopf kriegen. Meine Variante: Ich sage mir, Python macht grundsätzlich call-by-reference. Allerdings macht der *Zuweisungsoperator* was anderes als in C und Konsorten. (Nämlich Rebinding statt überschreiben einer Speicherzelle.) Damit kann man sich auch alles erklären ... Tschö, Torsten. -- Torsten Bronger Jabber-ID: torsten.bronger@jabber.rwth-aachen.de oder http://bronger-jmp.appspot.com
Am 12.11.2013 16:37, schrieb Torsten Bronger:
Hallöchen!
Alexander Langer schreibt:
[...]
Es geht um die Semantik. Ich halte die Aussage, das sei call-by-value schlicht für falsch. Man kann sich darauf einigen, dass Python es anders macht und es meinteswegen call-by-assign nennen. Ungewohnt ist es trotzdem.
Jeder muß das anders in seinen Kopf kriegen. Meine Variante: Ich sage mir, Python macht grundsätzlich call-by-reference. Allerdings macht der *Zuweisungsoperator* was anderes als in C und Konsorten. (Nämlich Rebinding statt überschreiben einer Speicherzelle.) Damit kann man sich auch alles erklären ...
Man kann natürlich immer versuchen, Äpfel mit Birnen zu vergleichen. Aber manchmal ist es weder ein Apfel noch eine Birne sondern eine Quitte. :) Noch mal: Python verwendet weder call-by-reference noch call-by-value. Es ist call-by-object, auch genannt call-by-object-sharing oder call-by-sharing. http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing
participants (6)
-
Achim Domma -
Alexander Langer -
Christian Heimes -
Michael Ziegler -
Stefan Schwarzer -
Torsten Bronger