Hi!
Ich habe hier gerade ein Problem an dem ich nicht weiterkomme, wäre schön wenn jemand ne Lösung wüßte:
Ich schreibe ein Programm mit wxPython, in dem ich Dateien lese und schreibe über pickle. Dafür hätte ich gerne Ladebalken. Prinzipiell ja auch kein Problem mit wxGauge und/oder wx.ProgressDialog. Leider bekomme ich von pickle nicht zurück, wieviel er bereits geladen oder gespeichert hat -sprich, ich kann für den Balken kein Maximum angeben und auch keine sinnvollen Zwischenwerte. Normalerweise würde ich an dieser Stelle so einen Fortschrittsbalken nehmen, der einfach nur hin und herwandert (so ähnlich wie ein Throbber). Das heißt in Java "indeterminate" und läßt sich als Paramter angeben.
Für wxPython gibt es das wohl auch laut google, aber nur für Mac.
Aber für Windows finde ich da gar nichts? Hat jemand ne Lösung, entweder für so einen "unbestimmten" Fortschrittsbalken, oder wie man von pickle sinnvolle Fortschrittswerte bekommt?
Bin dankbar für jede Hilfe!
Gruß,
Martin
wx.ProgressDialog für pickle.load
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Du könntest nicht direkt die Datei mit pickle laden, sondern erstmal Blockweise in einen String packen. Dabei kannst du einen Fortschrittsbalken laufen lassen. Nach dem die Datei geladen ist, kannst du es mit pickle umwandeln...
Aber wie groß sind deine Pickle Daten, das es so lange dauert, diese zu laden?
Aber wie groß sind deine Pickle Daten, das es so lange dauert, diese zu laden?
Nette Idee mit dem Umwandeln - vielleicht probiere ich das mal.
Riesig sind die Daten nicht, aber es fällt schon etwas an
Meine "Testdatei" hat 1,5MB, aber ich denke das wird bei ernsthafter Benutzung eher mehr. Also Größenordnung von einigen MB. Da braucht pickle dann ein paar Sekunden. Nicht wirklich lange, aber lange genug, daß ich gerne einen Fortschrittsbalken hätte
Gruß,
Martin
Riesig sind die Daten nicht, aber es fällt schon etwas an
Meine "Testdatei" hat 1,5MB, aber ich denke das wird bei ernsthafter Benutzung eher mehr. Also Größenordnung von einigen MB. Da braucht pickle dann ein paar Sekunden. Nicht wirklich lange, aber lange genug, daß ich gerne einen Fortschrittsbalken hätte
Gruß,
Martin
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Naja, dann ist das eigentliche laden der roh Daten aus der Datei ja in Burchteilen von Sek. fertig...
Du könntest natürlich auch noch faken... Das laden der Daten geht von 0-90% und das umwandeln, dann die restlichen Prozente...
Oder du speicherst einfach die Zeit, die ein laden + umwandel früher gedauert hat und machst einen spekulativen Fortschrittsbalken, beim nächsten mal... Aber ich weiß nicht ob sich der Aufwand lohnt
Du könntest natürlich auch noch faken... Das laden der Daten geht von 0-90% und das umwandeln, dann die restlichen Prozente...
Oder du speicherst einfach die Zeit, die ein laden + umwandel früher gedauert hat und machst einen spekulativen Fortschrittsbalken, beim nächsten mal... Aber ich weiß nicht ob sich der Aufwand lohnt
Habe mal versucht eine "file-like" Klasse dazwischen zu schalten. Das funktioniert soweit auch, aber es wird durch das ständige ausgeben des Fortschritts wesentlich langsamer.
Die "Dummy" Klasse `PlaylistEntry` ist nur da um meine Testdaten laden zu können.
Code: Alles auswählen
#!/usr/bin/env python
from __future__ import division
import os
class ReadFileWithCallback:
def __init__(self, fileobj, size, callback=lambda a, b: None):
self.fileobj = fileobj
self.size = size
self.callback = callback
self.close = fileobj.close
self.read_bytes = 0
@classmethod
def open(cls, filename, mode='r', callback=lambda a, b: None):
return cls(open(filename, mode), os.path.getsize(filename), callback)
def read(self, size=-1):
result = self.fileobj.read(size)
self.read_bytes += len(result)
return result
def readline(self, size=-1):
result = self.fileobj.readline(size)
self.read_bytes += len(result)
self.callback(self.read_bytes, self.size)
return result
def print_progress(current_bytes, max_bytes):
print '%6.2f%% (%d of %d kB)\r' % (current_bytes / (max_bytes / 100),
current_bytes // 1024,
max_bytes // 1024),
class PlaylistEntry:
pass
def test():
import pickle
cache_file = ReadFileWithCallback.open('.mkplaylist.cache',
'rb',
print_progress)
print 'start'
dummy = pickle.load(cache_file)
print '\nstop'
cache_file.close()
if __name__ == '__main__':
test()