with-fähige Classen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

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,
...
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

dmn it - ich habe python2.5 wie ich gerade erkenne...
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Geht trotzdem:

Code: Alles auswählen

from __future__ import with_statement
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

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
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

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]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Übrigens macht contextlib.closing genau das, also brauchst du diese Methoden nicht sondern kannst die Klasse einfach darüber wrappen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

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: ...
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

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!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ehh, dachte das wäre etwas praktischer. Ein Closing-Mixin oder Klassendekorator scheint nicht Teil der Stdlib zu sein.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

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.
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Ja, das ist natürlich freundlicher, dem Server noch "Tschüß" zu sagen. :)
Antworten