James Smith wrote: > Say an object like this exists: > class test: > a = "" > b = "" > > You pickle it. > > You change the object definition to have a new field: > class test > a = "" > b = "" > c = "" > > You read the pickled object. > Will it load but ignore the new field? > That is what I want.
Classes are pickled by name. You are free to replace them with whatever you want: >>> class Test: ... a = 1 ... b = 2 ... >>> import pickle >>> p = pickle.dumps(Test) >>> class Test: ... a = 10 ... b = 20 ... c = 30 ... >>> P = pickle.loads(p) >>> P.c 30 >>> P.a 10 >>> P is Test True If you introduce a new *instance* attribute that will not magically appear on unpickling: >>> class T: ... def __init__(self, a, b): ... self.a = a ... self.b = b ... def __str__(self): return "T(a={0.a}, b={0.b})".format(self) ... >>> t = T(1, 2) >>> print(t) T(a=1, b=2) >>> p = pickle.dumps(t) >>> class T: ... def __init__(self, a, b, c): ... self.a = a ... self.b = b ... self.c = c ... def __str__(self): return "T(a={0.a}, b={0.b}, c={0.c})".format(self) ... >>> print(T(10, 20, 30)) T(a=10, b=20, c=30) >>> v = pickle.loads(p) No problem so far as the initializer is not called so that the missing c is not a problem. But then: >>> print(v) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in __str__ AttributeError: 'T' object has no attribute 'c' One easy fix is to use a class attribute as the fallback: >>> T.c = "class attribute" >>> print(v) T(a=1, b=2, c=class attribute) But remember not to try this with mutable attributes. When `c` is a list v.c.append(42) will affect all instances with a missing `c` instance attribute. -- https://mail.python.org/mailman/listinfo/python-list