Seite 1 von 1

Seiteneffekt?

Verfasst: Samstag 15. August 2015, 16:13
von Sophus
Hallo Leute,

ich war gerade dabei eine (einfache) Liste an die Funktion zu übergeben. In diesem Zusammenhang ging ich dann wie folgt vor:

Code: Alles auswählen

>>> def func(list):
...     print list

>>> foo_list = [0,1,1,2,3,5,8]
>>> func(foo_list)


Und dabei stieß ich auf den Begriff "Seiteneffekt". Ich las auf einigen Seiten, dass dies ein schlechter Programmierstil sei, und man dies so nicht handhaben sollte. Und soweit ich es auch verstanden habe, wird hierbei nicht die Liste als solches übergeben, sondern nur der Verweis auf die Liste. Das heißt, in Wirklichkeit wurde die Liste gar nicht an die Funktion übergeben, sondern nur der Verweis wo die Liste sich befindet. Viel mehr wurde dafür plädiert, dass man die Liste als eine Kopie an die Funktion übergeben solle. Etwa so:

Code: Alles auswählen

>>> def func(list):
...     print list
... 
>>> foo_list = [0,1,1,2,3,5,8]
>>> func(foo_list[:])
Mit dieser sogenannten Slicing-Funktion [:] wird ja eine Kopie erstellt, und diese an die Funktion übergeben.

Soweit so gut, aber irgendwie habe ich das Gefühl, diesen Sachverhalt noch nicht ganz verinnerlicht zu haben. Was ist nun so "schlecht" an einem Seiteneffekt? Wieso sollte man den sogenannten "Seiteneffekt" verhindern? Welche Nachteile erkaufe ich mir? Und wieso sollte man eine Kopie an die Funktion übergeben? Wieso nicht den Verweis?

Re: Seiteneffekt?

Verfasst: Samstag 15. August 2015, 16:49
von Sirius3
@Sophus: Seiteneffekte sind die Nebenwirkungen der Medikamente. Man will sie im Normalfall nicht haben. Wenn eine Funktion dafür da ist, den Inhalt einer Liste zu ändern (sort_list) dann ist das kein Seiteneffekt, sondern gewollt. Hingegen eine Funktion, die von außen nicht den Anschein hat, den Inhalt zu ändern, sollte das auch nicht tun. Aber wo hast Du gelesen, dass man immer eine Kopie der Liste erstellen soll? Das ist nämlich genau der falsche Weg. Derjenige, der die Funktion schreibt, muß darauf achten, dass sie seiteneffektfrei ist, nicht derjenige der sie aufruft. Im Umkehrschluß, Funktionen, die Listen verändern müssen das gewollt und dokumentiert tun.

Re: Seiteneffekt?

Verfasst: Samstag 15. August 2015, 16:55
von Sophus
Hallo Siriu3,

ich habe dies hier gelesen. Im Abschnit "Seiteneffekt".

Re: Seiteneffekt?

Verfasst: Samstag 15. August 2015, 17:22
von Hyperion
@Sophus: Wir wissen aus mittlerweile vielen Threads daß du ziemlich beratungsresistent bist. Da ich von unterwegs mit dem Smartfone schreibe, nutze ich nicht die SuFu, um zu gucken ob wir Dir nicht schon einmal etwas zu diesem Kurs gesagt haben. Ich bin mir aber fast sicher - und falls nein, so ist dir das als Stammleser aber bereits sicherlich schon einmal über den Weg gelaufen, *was* wir hier empfehlen und was *nicht*.

Du hast jetzt gehört, wie es sich mit solchen pauschalen Aussagen verhält. Darüber hinaus gibt es ganz allgemein einige richtig gute Tutorials. Den Schluss daraus überlasse ich jetzt dir!

Re: Seiteneffekt?

Verfasst: Samstag 15. August 2015, 18:29
von cofi
Wenn eine Funktion etwas neben seiner Dokumentation und erst recht mit den Argumenten tut, sollte man das vermeiden.
Den verlinkten Absatz kann man aber schlicht nicht generell unterschreiben. Manchmal _will_ man diese Effekte, beispielsweise bei einer Funktion die sein Argument _in-place_ sortiert.

Man sollte sich einfach an das Principle of least Surprise halten.

Nebenbei: Es heisst Nebeneffekt, Seiteneffekt ist eine falsche Uebersetzung von "side effect".

Re: Seiteneffekt?

Verfasst: Samstag 15. August 2015, 20:50
von noisefloor
Hallo,

eine netter Nebeneffekt des Beispiels im 1. Post ist, dass es mit `list` einen äußerst schlechten Variablennamen benutzt, weil `list` in Buildin Funktion ist.

Code: Alles auswählen

>>> def func(list):
...     print(list)
...     list('abc')
... 
>>> a = [1, 2, 3]
>>> func(a)
[1, 2, 3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in func
TypeError: 'list' object is not callable
>>> >>> list('abc')
['a', 'b', 'c']
Ansonsten hatte ich beim Programmieren noch nie das Bedürfnis `func(foo_list[:])` zu schreiben. Weil: siehe Post von sirius3 :-)

Gruß, noisefloor