Is it possible to Uncickle class instances after converting from old to new?

In python, is it possible to scatter objects that were pickled as old-style python classes after converting to new styles? (That is, objects with different "class signatures"). *

For example, imagine some instances were saved as:

class foo: # old style 

and then several more objects were etched after the class was changed to inherit the object:

 class foo(object): # new style 

Objects that pickle.dump 'ed with one can be pickle.load ' ed with the same style class, but neither of them will load both. I think the strategy used by the brine changes is based on inheritance (the class that inherits from the object automatically defines the __reduce__ method, but the one that does not have inheritance does not). When you try to load inheritance with the inheritance of the old type from code without inheritance (defining the old style), I get the same argument error as in this question https://stackoverflow.com/a/166184/ although the second argument is redundant, it still modifies the "class signature" and the expected arguments and prevents loading. To solve this problem, I would be happy to write a loafer, although I am afraid that this may include two separate subclassed unpicklers a la the docs ... If I knew how to open each of them correctly, I would do it perfectly .

A little about my situation ... I use the TrialHandler class to save and reload button clicks and reaction times for behavior psychology experiments. We redesigned the TrialHandler class to inherit a more abstract baseTrialHandler, but at the same time temporarily changed the class signature to inherit from the object. However, we could not unzip the old trial_handler files, so it was modified. I would like to see data from the same experiment that was launched with both versions of the trial handler, and therefore I want to unlock both types of the saved log file in the same script.

Alternatively, if I cannot write a custom unpickler that will smooth out both objects, is there another way to serialize them? I tried to blame it directly on the barley, but it looks like I have to register the class as something that can be yaml'ized, anyway.

A full description of the description of the problem with specific errors can be found on the PsychoPy mailing list. Any blog posts explaining the details of intermediate etching, or even python inheritance, would be most welcome; the closest I found was a good explanation of why etching is unsafe , describing etching as a β€œsimple stacked virtual machine,” which is nice but doesn't get me enough to understand even the basics of disassembling myself.

+6
source share
1 answer

Movement in parts:

  • in Python there is no concept of class signature, although I got the idea from your question.
  • Not inheriting from an β€œobject” in a Python 2 program should be considered an error. Classes that are not inherited from an object - also called "old-style" classes, where it was simply stored for backward compatibility, when new style classes, Python 2.2 (circa 2000/2001) - old-style classes are much less consistent and lack many functions that make python is such a good language today.

Because of this: unpickle will attempt to deserialize the objects based on the class name (as in <module>.<class> ), as shown in the __class__.__name__ object during etching. Thus, you can have a naive way that when throwing an unpickle (it raises a TypeError), replace the available class with the same name and repeat the unickle operation Again: your classes should inherit from the "object" (more specifically, have a metaclass "based on type ")

As for the example I was talking about, write something:

 try: new_obj = pickle.load(data_stream) except TypeError: # if you know this was caused due to the new version of "Foo" class: current_foo = foomodule.Foo foomodule.Foo = foomodule.OldFoo new_obj = pickle.load(data_stream) foomodule.Foo = current_foo 
+5
source

Source: https://habr.com/ru/post/912540/


All Articles