Python

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
BeS
Moderator
Beiträge: 3236
Registriert: 17.04.2002 18:30:21
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Stuttgart
Kontaktdaten:

Python

Beitrag von BeS » 15.12.2007 00:51:02

Hallo,

kann mir das mal jemand erklären:

Code: Alles auswählen

>>> def sample(x, L=[]):
...              L.append(x)
...              print L
... 
>>> sample(1)
[1]
>>> sample(2)
[1, 2]
>>> sample(3)
[1, 2, 3]
>>> sample(3, [5])
[5, 3]
>>> sample(4)
[1, 2, 3, 4]
Warum bleibt da die Liste L über den Funktionsaufruf hinweg bestehen und wird erweitert? Normal müsste L doch auf dem Stack angelegt werden wenn die Funktion aufgerufen wird und am Ende wieder "abgeräumt" werden. Irgendwo scheint da aber was übrig zu bleiben und bei jedem weiteren Aufruf wird dann wieder darauf verwiesen???
Deine Unterstützung für Freie Software kostet dich nur wenige Minuten: www.fsfe.org/support

Ich spreche von Freier Software!

ulf
Beiträge: 39
Registriert: 22.09.2002 13:00:52

Beitrag von ulf » 15.12.2007 14:11:58

Frag den Chef:
http://docs.python.org/tut/node6.html#S ... 0000000000
--> Important warning: ...

Ulf

Benutzeravatar
BeS
Moderator
Beiträge: 3236
Registriert: 17.04.2002 18:30:21
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Stuttgart
Kontaktdaten:

Beitrag von BeS » 27.12.2007 01:51:05

Hallo,
ulf hat geschrieben:Frag den Chef:
http://docs.python.org/tut/node6.html#S ... 0000000000
--> Important warning: ...
Die Doku kenne ich :)

Die sagt aber auch nur das es so ist und nicht warum oder wie man das überhaupt macht.

Wie bereits gesagt, wenn eine Funktion aufgerufen wird, dann wird ein Aktivierungsblock mit den Übergabeparametern, lokalen Variablen usw. auf dem Stack angelegt. verlässt man die Funktion wird der Aktivierungsblock vom Stack abgeräumt. Man könnte jetzt sagen, dass Listen auf dem Heap angelegt werden, aber auch dann müsste der RC nach dem verlassen der Funktion bei 0 sein und die Liste abgeräumt werden.
Das wirft ja durchaus auch Fragen des Speichermanagement auf, wer geht schon davon aus, dass noch was im Speicher rumliegt, das es eigentlich im Programm gar nicht mehr gibt?


Was ich mich also frage ist:
1. Wie machen Python das?
2. (Viel wichtiger) Warum macht Python das?

Für mich ist das alles in allem irgendwie ein ziemlich "unlogisches" Feature.
Deine Unterstützung für Freie Software kostet dich nur wenige Minuten: www.fsfe.org/support

Ich spreche von Freier Software!

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 29.12.2007 12:14:16

BeS hat geschrieben:2. (Viel wichtiger) Warum macht Python das?
Wahrscheinlich, weil es anders nicht möglich ist, folgendes Beispiel:

Code: Alles auswählen

def foo():
    return 42

def bar(x=foo):
    return x()

def foo():
    return 49
Hier soll bar 42 zurückgeben, und nicht 49. Dasselbe Problem hast du, wenn foo eine Variable wäre. Hier muss der Wert, der zur Definitionszeit existiert, genommen werden. Das ist für [] als defaultparameter ein bekannter Fallstrick, aber man bleibt bei Python lieber konsistent: "Special cases aren't special enough to break the rules"

Antworten