Namespace on Peony Pickle

I got an error when I use pickle with unittest.

I wrote 3 program files:

  • for pickled class,
  • for a class that uses the class in # 1,
  • unittest for class testing in # 2.

and real codes are as follows.

# 1. ClassToPickle.py

import pickle class ClassToPickle(object): def __init__(self, x): self.x = x if __name__=="__main__": p = ClassToPickle(10) pickle.dump(p, open('10.pickle', 'w')) 

# 2. SomeClass.py

 from ClassToPickle import ClassToPickle import pickle class SomeClass(object): def __init__(self): self.pickle = pickle.load(open("10.pickle", 'r')) self.x = self.pickle.x print self.x if __name__ == "__main__": SomeClass() 

# 3. SomeClassTest.py

 import unittest from SomeClass import SomeClass from ClassToPickle import ClassToPickle # REQUIRED_LINE class SomeClassTest(unittest.TestCase): def testA(self): sc = SomeClass() self.assertEqual(sc.x, 10) def main(): unittest.main() if __name__ == "__main__": main() 

First, I ran the first program to make a pickle file.
And then, when I run only the program file No. 2 (ie Enter "python SomeClass.py"), it works.
And when I run only program number 3 (ie Enter "python SomeClassTest.py"), it also works.

However, when I run program # 3 as "unit-test" in eclipse + pydev, it returns the error message below.

==================================================== =====================
ERROR: testA (SomeClassTest.SomeClassTest)
-------------------------------------------------- --------------------
Traceback (last last call):
$ File "/home/tmp/pickle_problem/SomeClassTest.py", line 9, in Testa
sc = SomeClass ()
$ File "/home/tmp/pickle_problem/SomeClass.py", line 8, in INIT
self.pickle = pickle.load (open ("10.pickle", 'r'))
$ File "/usr/lib/python2.7/pickle.py", line 1378, in download
return Unpickler (file) .load ()
$ File "/usr/lib/python2.7/pickle.py", line 858, in download
dispatchkey
File "/usr/lib/python2.7/pickle.py", line 1090, in load_global
klass = self.find_class (module, name)
$ File "/usr/lib/python2.7/pickle.py", line 1126, in find_class
klass = getattr (mod, name)
$ AttributeError: the 'module' object does not have the 'ClassToPickle' attribute

-------------------------------------------------- --------------------
Ran 1 test in 0.002s

FAILED (errors = 1)

And also, when I commented on the line that imports the ClassToPickle class (line 3 in program # 3 and is commented as "REQUIRED_LINE"), it does not work and returns the error message described below.

E
=================================================== =====================
ERROR: testA ( main .SomeClassTest)
-------------------------------------------------- --------------------
Traceback (last last call):
File "SomeClassTest.py", line 9, in testA
sc = SomeClass ()
File "/home/tmp/pickle_problem/SomeClass.py", line 8, in init
self.pickle = pickle.load (open ("10.pickle", 'r'))
File "/usr/lib/python2.7/pickle.py", line 1378, in download
return Unpickler (file) .load ()
File "/usr/lib/python2.7/pickle.py", line 858, in download
dispatchkey
File "/usr/lib/python2.7/pickle.py", line 1090, in load_global
klass = self.find_class (module, name)
File "/usr/lib/python2.7/pickle.py", line 1126, in find_class
klass = getattr (mod, name)
AttributeError: the 'module' object does not have the 'ClassToPickle' attribute

-------------------------------------------------- --------------------
Ran 1 test in 0.001s

FAILED (errors = 1)

I assume the problem is with the namespace in python, but I don’t know what exactly happened and what I can do to resolve it.

How can I run the unit-test program correctly (in eclipse + pydev) "# 3,
and run program # 3 on the command line without a line that imports ClassToPickle?
Please help me.

+5
python namespaces pickle
source share
1 answer

This is because __main__.ClassToPickle != ClassToPickle.ClassToPickle , think of it this way:

When you pickle an instance of the ClassToPickle class in the ClassToPickle.py script, the pickle module will sort the entire class reference, which means that it will collect the name of the module where the class was defined, and because you executed the ClassToPickle.py script this means that the module will set to __main__ , which means the pickle module will sort __main__.ClassToPickle .

And when you tried to load the processed instance, it fails because it did not find the instance class, which is __main__.ClassToPickle , and not the one you imported with from ClassToPickle import ClassToPickle , because this is the last value of ClassToPickle.ClassToPickle .

The fix will be the creation of another script that will handle dumping instead of doing this in ClassToPickle.py for example.

 import pickle from ClassToPickle import ClassToPickle if __name__=="__main__": p = ClassToPickle(10) pickle.dump(p, open('10.pickle', 'w')) 
+6
source share

All Articles