Python: __getattr__メソッド付きのオブジェクトでcPickleで保存

class TestClass1:
    def __init__(self, h):
        self.h = h
    def __getattr__(self, attrname):
        return getattr(self.h, attrname)

これだと、

testc = TestClass1({"Apple": "Ringo", "Orange": "Mikan"})
    
print testc.keys()
print testc.values()    

fh = open("/tmp/cPickle_test1.pkl", "wb")
cPickle.dump(testc, fh, True)
fh.close()

fh_r = open("/tmp/cPickle_test1.pkl", "rb")
testc_loaded = cPickle.load(fh_r)
    
print testc_loaded.keys()
print testc_loaded.values() 


Traceback (most recent call last):
  File "/Users/golgo8128/UNIX/rs_Progs/rs_Python/rs_Python_Pack/Test_Packages/cPickle/cPickle_getattr_test1.py", line 34, in <module>
    testc_loaded = cPickle.load(fh_r)
  File "/Users/golgo8128/UNIX/rs_Progs/rs_Python/rs_Python_Pack/Test_Packages/cPickle/cPickle_getattr_test1.py", line 9, in __getattr__
    return getattr(self.h, attrname)
:
:
  File "/Users/golgo8128/UNIX/rs_Progs/rs_Python/rs_Python_Pack/Test_Packages/cPickle/cPickle_getattr_test1.py", line 9, in __getattr__
    return getattr(self.h, attrname)
  File "/Users/golgo8128/UNIX/rs_Progs/rs_Python/rs_Python_Pack/Test_Packages/cPickle/cPickle_getattr_test1.py", line 9, in __getattr__
    return getattr(self.h, attrname)
RuntimeError: maximum recursion depth exceeded

ようなエラーが出てしまう。これを回避するためには、

class TestClass2:
    def __init__(self, h):
        self.h = h
    def __getattr__(self, attrname):
        if attrname == "__setstate__":
            raise AttributeError("%r object has no attribute %s" %
                                 (self.__class__, attrname))
        else:
            return getattr(self.h, attrname)

のように、__getattr__の部分に__setstate__が呼ばれたときの処理を加える。