読者です 読者をやめる 読者になる 読者になる

シリアライズ関数

Python

ふとしたことでシリアライズすることになったのですが、
つい横柄して以下のようなコードを書いたらまともに動きませんでした。

import pickle

class Sample(object):
    
    def __init__(self, value):
        self.value = value
    
    def save(self, fname):
        pickle.dump(self, open(fname, 'wb'))
    
    def load(self, fname):
        self = pickle.load(open(fname, 'rb'))

if __name__ == '__main__':
    a = Sample('hoge')
    a.save('test.dat')
    print '[%s]' % a.value
    
    b = Sample('')
    b.load('test.dat')
    print '[%s]' % b.value
    
    assert a.value == b.value


当たり前だ!というお叱りの声が聞こえてきそうですが、
下記のようなコードを避けるためについ出来心で書いてしまったのです。

class Sample(object):
    ... 略
    def load(self, fname):
        tmp = pickle.load(open(fname, 'rb'))
        self.value = tmp.value

これを避けたい理由は言うまでもないかと思いますが、
クラスの変数を __init__ に新たに追加したときに
load()関数もメンテしなければならなくなるからです。


結局下記のような実装にしました。

import pickle
import copy

class Sample(object):
    
    def __init__(self, value):
        self.value = value
    
    def save(self, fname):
        pickle.dump(self, open(fname, 'wb'))
    
    def load(self, fname):
        tmp = pickle.load(open(fname, 'rb'))
        for key, value in tmp.__dict__.items():
            self.__dict__[key] = copy.deepcopy(value)

if __name__ == '__main__':
    a = Sample('hoge')
    a.save('test.dat')
    print '[%s]' % a.value
    
    b = Sample('')
    b.load('test.dat')
    print '[%s]' % b.value
    
    assert a.value == b.value


というわけで、ちょっと疲れてる自慢でした。