def foo(*args, bar=''): -> Fehler bei 2.5, läuft unter 2.

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

Code: Alles auswählen

def mycallback(foo):
    print foo

class foobar:
    def __init__(self, *args, callback=''):
        if callback == '':
            self.callback = emptycallback
        else:
            self.callback = callback
        self.foo(*args)

    def emptycallback(self):
        pass

    def foo(self, *args):
        print ', '.join(args)
        self.callback('method foo')

foobar(*rang(10), callback=mycallback)

Um einen Code dieser Art geht es mir dieses mal.
Im speziellen soll eine Class die von ftplib.FTP erbt mir Statusmeldungen an eine Funktion meiner Wahl geben (also z.B. 'downloading %s' % filename)


Unter python2.6 (Linux, 32bit) ist das auch kein Problem.
Die Probleme gibt es bei python2.5 (Linux, 32bit).

Da bekomme ich einen Syntaxerror, solange ich das callback='' hinter den *args lasse.

Gibt es hier eine Möglichkeit python2.5 dazu zu bringen, das dennoch zu akzeptieren?
(z.B. __future__)

lg,
...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

... hat geschrieben: Unter python2.6 (Linux, 32bit) ist das auch kein Problem.
Wirklich?

Code: Alles auswählen

In [88]: def bar(*args, callback=None):
------------------------------------------------------------
   File "<ipython console>", line 1
     def bar(*args, callback=None):
                           ^
SyntaxError: invalid syntax


In [89]: def foo(callback=None, *args):
(Python 2.6 auf nem 64 Bit Arch Linux)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Das sollte bei allen Python-Versionen < 3.0 einen Fehler liefern. Einen future-Import wüsste ich jetzt nicht. Ich würde es so lösen:

Code: Alles auswählen

def __init__(self, *args, **kwds):
    try:
        self.callback = kwds["callback"]
    except KeyError:
        self.callback = foobar.emptycallback
    self.foo(*args)
Statt einen leeren String für "nichts" solltest du besser None verwenden. Genau für solche Dinge ist es gedacht. Und wenn du nächstes Mal ein Beispiel bereitstellst, dann mache es wenigstens ausführbar und in vernünftigem/idiomatischem Code. War hier zwar nicht nötig, aber das erhöht durchaus die Antwortchancen.
Das Leben ist wie ein Tennisball.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Code: Alles auswählen

class FooBar(object):
    def __init__(self, *args, **kwargs):
        self.callback = kwargs.pop("callback", lambda: None)

    def foo(self, *args):
        print ", ".join(args)
        self.callback("method foo")

def my_callback(foo): print foo
FooBar(*range(10), callback=my_callback)
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

Stimmt... wirft doch einen Fehler... ich war mir gerade ganz sicher, das es noch funktioniert hatte...


EyDu, deine Lösung gefällt mir!

Vielen Dank...
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

Ach mist...
Der Fehler liegt wo anders seh ich grade...

Ich habe eine Klasse:

Code: Alles auswählen

class FtpConnection(ftplib.FTP):
   def __init__(self, host, port, user, passwd, callback=''):
      if callback == ''
         self.callback = self.emptycallback
      else:
         self.callback = callback
      [...]
Die Logindaten hab ich in nem Tuple, und wollte darum so aufrufen:

Code: Alles auswählen

Ftp = FtpConnection(*connectiondata, callback=mycallback)
Da wirft jetzt 2.5 den Error, und 2.6 nicht.


(Ich hoffe, diesmal hab ichs richtig)[/code]
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Kann ich auch nicht nachvollziehen:

Code: Alles auswählen

In [91]: def foo(a, b, c=None):
   ....:     print a, b, c
   ....:     
   ....:     

In [92]: foo(1, 2)
1 2 None

In [93]: data = ["hallo", "welt"]

In [94]: foo(*data)
hallo welt None

In [95]: foo(*data, c="Python")
hallo welt Python
Sicher, dass es ein Syntax-Fehler ist? Ich würde denken, dass ggf. die Anzahl der Parameter von Deinem "connectiondata"-Objekt nicht passen.
Das gibt aber einen TypeErrror...

edit: Mist, ok, ich hab hier ja auch nur 2.6... :oops:
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

Code: Alles auswählen

michael@michael-desktop:/media/disk/python2.5.4/App/Projekte/ereader$ python2.5 e.reader.py
  File "e.reader.py", line 302
    with FtpConnection(*self.FtpConnectionData, callback=self.updateStatus) as self.Ftp:
                                                       ^
SyntaxError: invalid syntax
michael@michael-desktop:/media/disk/python2.5.4/App/Projekte/ereader$ python2.6 e.reader.py
True
michael@michael-desktop:/media/disk/python2.5.4/App/Projekte/ereader$ 
with_statement wurde importiert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Du solltest natürlich noch die init-Methode der Basisklasse in deiner eigenen init-Methode aufrufen ;-)

@DasIch: Du solltest aufhören Datenstrukturen sinnlos zu verändern, das hast du beim rekursiven Umkehren auch schon gemacht ;-) Verwende statt pop besser get.
Das Leben ist wie ein Tennisball.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

@EyDu Wenn man .pop() bei kwargs nutzt kann ich aber danach noch ein if kwargs: raise TypeError("unexpected keyword argument") machen ;) Da die Datenstruktur sowieso nicht direkt vom User kommt habe ich auch keine Seiteneffekte.
Antworten