New style classes und pickle

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.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

New style classes und pickle

Beitragvon Leonidas » Donnerstag 3. Juni 2004, 18:45

Hallo.
Ich habe versucht eine new style klasse, die __slots__ definiert mit pickle zu serialisieren, aber das geht nicht? Wieso?

grüße,
Leonidas
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Beitragvon Milan » Freitag 4. Juni 2004, 19:45

Hi. Zeig doch bitte mal etwas Quellcode. Ohne können wir nur ins blaue raten... :wink:
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Montag 7. Juni 2004, 07:25

Der Code ist:

Code: Alles auswählen

class Settings(object):
    # what is __getstate__ ?
    #__slots__ = ['wordmode', 'casemode', 'errormode', 'searchmode', 'debug', 'showparabar', 'showumlautbar']
    def __init__(self, wordmode='full', casemode='ignore',\
            errormode='0error', searchmode='simple',\
            showparabar=False, showumlautbar=False, debug=False):
        """This constructor is able to set up nearly everything"""
        self.wordmode = wordmode
        self.casemode = casemode
        self.errormode = errormode
        self.searchmode = searchmode
        self.showparabar = showparabar
        self.showumlautbar = showumlautbar
        self.debug = debug
   
    def SetWordmode(self, wordmode):
        """Changes the wordmode in the settings after it is verified"""
        if wordmode == 'full' or wordmode == 'partial':
            self.wordmode = wordmode
        else:
            raise ValueError('No such wordmode allowed: %s' % wordmode)
   
    def GetWordmode(self):
        """Returns the wordmode"""
        return self.wordmode
   
    def SetCasemode(self, casemode):
        """Changes the casemode in the settings after it is verified"""
        if casemode == 'exact' or casemode == 'ignore':
            self.casemode = casemode
        else:
            raise ValueError('No such casemode allowed: %s' % casemode)
   
    def GetCasemode(self):
        """Returns the casemode"""
        return self.casemode
   
    def SetErrormode(self, errormode):
        """Changes the errormode in the settings after it is verified"""
        if errormode == '0error' or errormode == '1error' or errormode == '2error' or errormode == '3error' or errormode == '4error' or errormode == 'bestmatch':
            self.errormode = errormode
        else:
            raise ValueError('No such errormode allowed: %s' % errormode)
   
    def GetErrormode(self):
        """Returns the errormode"""
        return self.errormode
   
    def SetSearchmode(self, searchmode):
        """Changes the searchmode in the settings after it is verified"""
        if searchmode == 'simple' or searchmode == 'regex':
            self.searchmode = searchmode
        else:
            raise ValueError('No such searchmode allowed: %s' % searchmode)
   
    def GetSearchmode(self):
        """Returns the searchmode"""
        return self.searchmode

Ich habe hier slots auskommentiert, dann geht es, aber ich will die ja nutzen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Beitragvon Milan » Donnerstag 10. Juni 2004, 19:11

Hi. Ich hab mich jetzt nocheinmal durch die Docu's gewühlt... wie es ausschaut müssen new-style Klassen die Methoden __getstate__ und __setstate__ implementieren (hier das ganze als anderes Bsp.) Die regeln dann, was gepickelt wird und was nicht. So kann also __getstate__ ein Dict mit allen wichtigen Werten übergeben (also alles, was in __slots__ steht) und dann wird das Dict gepickelt. Beim unpickeln wird dann __setstate__ mit dem Dict gerufen und dann werden einfach alle Werte wieder gesetzt. Nicht gerade komfortabel, aber machbar. Bsp:

Code: Alles auswählen

class test(object):
    __slots__=["x"]
    def __init__(self,x):
        self.x=x
    def __getstate__(self):
        erg={}
        for i in self.__slots__:
            erg[i]=getattr(self,i)
        return erg
    def __setstate(self,dict):
        for i in dict:
            setattr(self,i,dict[i])


hth, Milan
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 10. Juni 2004, 19:27

also ich habe mal folgendes gemacht:
- slots wieder 'einkommentiert'
- folgenden code eingebaut (und nur den):

Code: Alles auswählen

def __getattr__(self):
    return self.__slots__

Damit scheint es zu gehen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Beitragvon Milan » Donnerstag 10. Juni 2004, 20:00

Hi. Das würde ich aber auf keinen Fall machen... probier mal Settings().wordmode zu rufen, dass dürfte nun einen Fehler geben (sofern du nicht von object ableitest. Dann wird intern __getattribute__ statt __getattr__ gerufen). Aber trotzdem ist __getattr für was anderes da, als eine Liste (nicht definiert, da __slots__ auskommentiert) zurückzugeben.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Sonntag 20. Juni 2004, 08:58

Du hast recht (es geht schon beim unpickeln nicht...). Deswegen habe ich mal deinen COde eingebaut:

Code: Alles auswählen

def __getstate__(self):
        erg={}
        for i in self.__slots__:
            erg[i]=getattr(self,i)
        return erg

Da kommt aber dann:

Code: Alles auswählen

Traceback (most recent call last):
  File "c:\ding.py", line 1157, in ?
    conf = pickle.load(file(picklename))
  File "C:\PROGRA~1\Python\Lib\pickle.py", line 1390, in load
    return Unpickler(file).load()
  File "C:\PROGRA~1\Python\Lib\pickle.py", line 872, in load
    dispatch[key](self)
  File "C:\PROGRA~1\Python\Lib\pickle.py", line 1244, in load_build
    inst.__dict__.update(state)
AttributeError: 'Settings' object has no attribute '__dict__'

Was kann ich dann machen?
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Gast

Beitragvon Gast » Sonntag 20. Juni 2004, 18:01

Da muss man das neue pickle protokol verwenden, das noch nicht standart ist...

http://docs.python.org/lib/node64.html

Da musst du als protokol 2 nehmen (pickle.HIGHEST_PROTOCOL)

also zb dumps(objekt,2)
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 24. Juni 2004, 12:15

also mit dump(..., pickle.HIGHTEST_PROTOCOL) gibt es den gleichen fehler.
My god, it's full of CARs! | Leonidasvoice vs Modvoice

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]