Seite 1 von 1

with-fähige Classen

Verfasst: Montag 22. Februar 2010, 14:50
von ...
Hallo,


Ich schreibe mir gerade eine Classe für den Zugriff auf einen FTP-Server mittels ftplib.

Da ich auch hier darauf achten sollte, das die Verbindung immer richtig beendet wird, wäre ja hier entweder 'try:' & 'finally:' benötigt oder 'with'... wenn letzteres geht.

Wie kann ich es so hinbekommen das dieser Befehl keine Fehlermeldung mehr wirft:

Code: Alles auswählen

with FTP_Connection as Ftp:
     do_what_i_want()
Der Fehler ist jener:

Code: Alles auswählen

>>> <string>:30: Warning: 'with' will become a reserved keyword in Python 2.6
execfile(r'C:\FTP.py')
C:\FTP.py:30: Warning: 'with' will become a reserved keyword in Python 2.6
Traceback (most recent call last):
  File "C:\FTP.py", line 30
    with FTP_Connection('dl4002', '6', '6') as Ftp:
                      ^
SyntaxError: invalid syntax

Ich habe gelesen, es benötige eine __enter__() und eine __exit__() funktion.
Wie müssen die aussehen? Worin (abgesehen vom Namen) unterscheidet sich __enter__() und __init__()?


lg,
...

Verfasst: Montag 22. Februar 2010, 14:56
von ...
dmn it - ich habe python2.5 wie ich gerade erkenne...

Verfasst: Montag 22. Februar 2010, 15:03
von HerrHagen
Geht trotzdem:

Code: Alles auswählen

from __future__ import with_statement

Verfasst: Montag 22. Februar 2010, 15:13
von cofi
Nun `__enter__` und `__exit__` muessen einfach existieren, damit du `with` nutzen kannst (Neben anderen Sachen, siehe link) .
Die Bedeutung sollte relativ klar sein. `__init__` hat hier gar nichts zu suchen, dass kuemmert sich um die Initialisierung und hat nichts mit dem Kontext-Protokoll zu tun.

Wenn es eine `close` Methode gibt, musst du deine Klasse auch nicht umschreiben `contextlib.closing` erstellt einen passenden Kontextmanager daraus.

http://docs.python.org/whatsnew/2.6.htm ... t-managers

Verfasst: Montag 22. Februar 2010, 15:26
von ...
Juhu - jetzt funktioniert es.
Ich hatte gedacht, __init__ sei einfach die Funktion die zu beginn aufgerufen wird, wenn die Classe instanziert wird...
Und __enter__ sah für mich da recht gleich aus :S


Hab jetzt die Zeilen:

Code: Alles auswählen

def __enter__(self):
    return self

def __close__(self, *args):
    self.close()
eingefügt - und es Funktioniert :)

vielen Dank cofi & HerrHagen[/code]

Verfasst: Montag 22. Februar 2010, 15:29
von Leonidas
Übrigens macht contextlib.closing genau das, also brauchst du diese Methoden nicht sondern kannst die Klasse einfach darüber wrappen.

Verfasst: Montag 22. Februar 2010, 15:43
von ...
Leonidas hat geschrieben:Übrigens macht contextlib.closing genau das, also brauchst du diese Methoden nicht sondern kannst die Klasse einfach darüber wrappen.
...

... was mir leider zu hoch ist :oops: ...

Verfasst: Montag 22. Februar 2010, 15:55
von mkesper
Wie im Beispiel unter http://docs.python.org/whatsnew/2.6.htm ... lib-module ganz unten:

Code: Alles auswählen

import ftplib
from contextlib import closing

with closing(ftplib.FTP(your_host)) as Ftp:
    do_what_you_want()
Ungetestet!

Verfasst: Montag 22. Februar 2010, 15:59
von Leonidas
Ehh, dachte das wäre etwas praktischer. Ein Closing-Mixin oder Klassendekorator scheint nicht Teil der Stdlib zu sein.

Verfasst: Montag 22. Februar 2010, 16:11
von ...
Ahso... das bedeutet wrappen :)

Bleibe trotzdem bei meiner Variante.
So muss ich nicht self.close() aufrufen, sondern self.quit(), welches dem FTP-Server noch ein QUIT-cmd übermittelt.
Außerdem muss man so nicht jedesmal wenn man es verwenden will diesen Wrapper wieder verwenden.

Anundfürsich hätte es so Funktioniert, mkesper.

Verfasst: Montag 22. Februar 2010, 16:21
von mkesper
Ja, das ist natürlich freundlicher, dem Server noch "Tschüß" zu sagen. :)