Seite 1 von 1

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

Verfasst: Sonntag 7. März 2010, 15:33
von ...

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,
...

Re: def foo(*args, bar=''): -> Fehler bei 2.5, läuft unte

Verfasst: Sonntag 7. März 2010, 15:48
von Hyperion
... 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)

Verfasst: Sonntag 7. März 2010, 15:51
von EyDu
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.

Verfasst: Sonntag 7. März 2010, 15:53
von DasIch

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)

Verfasst: Sonntag 7. März 2010, 15:56
von ...
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...

Verfasst: Sonntag 7. März 2010, 16:09
von ...
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]

Verfasst: Sonntag 7. März 2010, 16:15
von Hyperion
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:

Verfasst: Sonntag 7. März 2010, 16:23
von ...

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.

Verfasst: Sonntag 7. März 2010, 16:51
von EyDu
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.

Verfasst: Sonntag 7. März 2010, 17:00
von DasIch
@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.