Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Lernbeispiel für Komposition mit Klassen macht Schwierigkeiten

15 views
Skip to first unread message

Jan-Herbert Damm

unread,
Oct 13, 2009, 6:00:53 AM10/13/09
to

Hallo zusammen,

ich lerne Python mit "Lutz, Ascher: Einführung in Python". Folgendes Beispiel
aus Kapitel 22 kann ich nicht korrekt reproduzieren und wundere mich.

Kurzform der Frage:

dies funktioniert nicht:

>>> import bspmodul
>>> name = bspmodul.BspKlasse(open('spam.txt'), open('spamout.txt', 'w'))
>>> name.bspmethode()
# spamout.txt wird zwar erstellt, ist aber leer

dies funktioniert:

>>> import bspmodul
>>> bspmodul.BspKlasse(open('spam.txt'), open('spamout.txt', \
'w')).bspmethode()
# spamout.txt entspricht den erwartungen

Zwischen diesen beiden Aufrufen, dürfte doch eigentlich kein Unterschied
bestehen, oder?

Auführlich:

Es geht darum mit Klassen und Polymorphie eine vielfältig verwendbare
Funktionalität zu implementieren, bei der ein Datenstrom gelesen, konvertiert
und geschrieben werden kann. Dazu:

http://dpaste.com/106545/

Ich habe Verständnis wenn Euch dies alles zu wirr oder umfangreich ist. Ich
probiere das mit dpaste zum ersten mal und kann kann die Frage noch nicht
besser auf den Punkt bringen.

Dank

jan

Diez B. Roggisch

unread,
Oct 13, 2009, 6:18:32 AM10/13/09
to
Jan-Herbert Damm wrote:

Du hast einen Fehler in der Indentation der "converter"-methode.

Der ist aber nicht ursaechlich. Der Grund ist ein anderer - im zweiten Fall
erzeugst du keine Referenz auf den Prozessor. Darum wird der nach Aufruf
der "process"-methode garbage-collected. Und in dem Moment werden die Files
geschlossen, und das OS flusht die Daten auf die Platte.

Das waere auch der Fall, wenn du das ganze als Skript laufen liessest.

Weil du aber scheints IPython verwendest, fliegt noch eine Referenz rum, und
die Sachen werden nicht abgeraeumt.

Alles klar?

MfG Diez

Jan-Herbert Damm

unread,
Oct 13, 2009, 9:26:49 AM10/13/09
to
Diez, danke!

Diez B. Roggisch <de...@nospam.web.de> schrieb:


>
> Du hast einen Fehler in der Indentation der "converter"-methode.

oh, lange gesucht, aber jetzt doch gefunden...


>
> Der ist aber nicht ursaechlich. Der Grund ist ein anderer - im zweiten Fall
> erzeugst du keine Referenz auf den Prozessor.

hm, die Bedeutung dieses Satzes kriege ich nicht in den Kopf. Vielleicht
hilft Tip inwiefern ich diese Referenz im ersten Fall (durch IPython) erzeuge?


> Darum wird der nach Aufruf
> der "process"-methode garbage-collected. Und in dem Moment werden die Files
> geschlossen, und das OS flusht die Daten auf die Platte.
>
> Das waere auch der Fall, wenn du das ganze als Skript laufen liessest.
>
> Weil du aber scheints IPython verwendest, fliegt noch eine Referenz rum, und
> die Sachen werden nicht abgeraeumt.

In der Tat habe ich jetzt festgestellt, daß das Beispiel in der "normalen"
Python-shell funktioniert (und übrigens auch wenn ich es als skript laufen
lasse - im Selbsttest eingebaut).
>
> Alles klar?
noch nicht ganz, ich grübele noch

jan

Diez B. Roggisch

unread,
Oct 13, 2009, 9:48:31 AM10/13/09
to
Jan-Herbert Damm wrote:

Python verwendet fuer die Speicherverwaltung sogenanntes refernce-counting.

D.h. jedesmal wenn man eine Referenz auf ein Objekt anlegt, wird ein Counter
innerhalb des objektes hochgezaehlt, und umgekehrt wenn eine Referenz
wegfaellt, wird er dekrementiert. Wenn er 0 erreicht hat, wird das Objekt
zerstoert, und dabei werden natuerlich auch alle Referenzen, die es
seinerseits hat, ebenfalls zerstoert - und damit auch potentiell Objekte,
auf die es zeigt.

Eine Referenz zu erzeugen ist ein hochtrabender Satzbaustein fuer

name = ausdruck

Damit wird das Objekt, das sich *hinter* "ausdruck" verbirgt ueber "name"
referenziert.

Wenn du nun zB

del name

machst, dann wird der Refernzcounter des Objektes um eins erniedrigt.

Nun zu deinem Beispiel: du machst

prog = Uppercase(open('/tmp/spam.txt'), open('/tmp/spamout.txt', 'w'))
prog.process()

Damit ist das Uppercase-objekt uebern den Namen "prog" einmal referenziert.
Und seinerseits verweist es auf "reader" und "writer", die File-Objekte.

Wenn du nun (alles in der interaktiven Shell)

del prog

machst - dann sollet dein Problem verschwunden sein. Weil erst das
Uppercase-Objekt verschwunden ist, und dann dessen geoeffnete Files.

Referenzen auf Objekte sind natuerlich auch innerhalb von anderen Objekten
moeglich, zb

foo = []
foo.append(Uppercase(...))

Dann wuerde ein

del foo[0]

helfen.

Klarer?

Diez

Jan-Herbert Damm

unread,
Oct 13, 2009, 11:24:43 AM10/13/09
to

Diez B. Roggisch <de...@nospam.web.de> schrieb:

> Wenn du nun (alles in der interaktiven Shell)

>
> del prog
>
> machst - dann sollet dein Problem verschwunden sein. Weil erst das
> Uppercase-Objekt verschwunden ist, und dann dessen geoeffnete Files.

ja! so geht es, danke.
Die Ausführliche Erklärung hat sehr geholfen.

> Referenzen auf Objekte sind natuerlich auch innerhalb von anderen Objekten
> moeglich, zb
>
> foo = []
> foo.append(Uppercase(...))
>
> Dann wuerde ein
>
> del foo[0]
>
> helfen.
>
> Klarer?

wesentlich klarer. Wenn ich es als skript laufen lasse werden ja auch die
objekte wieder zerstört, jetzt muss ich nur nochmal testen warum es bei der
normalen python-shell funktionierte im Gegensatz zu Python. Möglicherweise
hatte ich aber diese Shell beendet und dann nach der Datei geschaut, während
ich bei ipython immer mit >>>!cat ... aus ipython selbst heraus gearbeitet
hatte.

jan

0 new messages