Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding extra fields to an existing namedtuple object and unpickling

I have some data in the pickled format with instances of below objects:

Point = namedtuple('Point', ['x',])

Now I want to extend the Point object to add another variable 'y' but also keep this compatible with the data I already have pickled.

Below is what I tried, but seems to fail. I also tried playing around with the code to make a Point class by setting the y parameter as optional when making the Point object, but that did not work as well. Any ideas on how to proceed?

from collections import namedtuple
Point = namedtuple('Point', ['x'])
i = Point(1)
import cPickle
pick=cPickle.dumps(i)
Point = namedtuple('Point', ['x', 'y'])
cPickle.loads(pick)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 22, in __repr__
TypeError: not enough arguments for format string
like image 338
Mohit Avatar asked Oct 28 '22 21:10

Mohit


1 Answers

Tuples are immutable. Unpickle first, than make a new point with a different namedtuple class and use the attribute x from the old point. Using the same name for the class Point should have the effect you are after:

Point = namedtuple('Point', ['x'])
i = Point(1)
pick=cPickle.dumps(i)


def unpickle_point(dumped_obj):
    Point = namedtuple('Point', ['x'])
    point = cPickle.loads(pick)
    Point = namedtuple('Point', ['x', 'y'])
    return Point(point.x, 2)

new_point = unpickle_point(pick)

Now:

>>> new_point
Point(x=1, y=2)
like image 95
Mike Müller Avatar answered Nov 11 '22 09:11

Mike Müller