Seite 1 von 1

New style classes und pickle

Verfasst: Donnerstag 3. Juni 2004, 18:45
von Leonidas
Hallo.
Ich habe versucht eine new style klasse, die __slots__ definiert mit pickle zu serialisieren, aber das geht nicht? Wieso?

grüße,
Leonidas

Verfasst: Freitag 4. Juni 2004, 19:45
von Milan
Hi. Zeig doch bitte mal etwas Quellcode. Ohne können wir nur ins blaue raten... :wink:

Verfasst: Montag 7. Juni 2004, 07:25
von Leonidas
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.

Verfasst: Donnerstag 10. Juni 2004, 19:11
von Milan
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

Verfasst: Donnerstag 10. Juni 2004, 19:27
von Leonidas
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.

Verfasst: Donnerstag 10. Juni 2004, 20:00
von Milan
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.

Verfasst: Sonntag 20. Juni 2004, 08:58
von Leonidas
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?

Verfasst: Sonntag 20. Juni 2004, 18:01
von Gast
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)

Verfasst: Donnerstag 24. Juni 2004, 12:15
von Leonidas
also mit dump(..., pickle.HIGHTEST_PROTOCOL) gibt es den gleichen fehler.