Python: pickle error: __new__() takes exactly 2 arguments (1 given)

3.4k views Asked by At

Related: pickle load error "__init__() takes exactly 2 arguments (1 given)"

import cPickle as pickle

pklfile = "test.pkl"

all_names = {}
class Name(object):
    def __new__(cls, c, s="", v=""):
        name = "%s %s %s" % (c, s, v)
        if all_names.has_key(name):
            return all_names[name]
        else:
            self = all_names[name] = object.__new__(cls)
            self.c, self.s, self.v = c, s, v

        return self

with open(pklfile, 'wb') as output:
    pickle.dump(Name("hi"), output, pickle.HIGHEST_PROTOCOL)

with open(pklfile, 'rb') as input:
    name_obj = pickle.load(input)

OUTPUT:

Traceback (most recent call last):
  File "dopickle.py", line 21, in <module>
    name_obj = pickle.load(input)
TypeError: __new__() takes at least 2 arguments (1 given)

Is it possible to make this work without having the second argument as optional?

1

There are 1 answers

0
Paul Rooney On BEST ANSWER

Use __getnewargs__, which is called when the object is pickled and provides a tuple of extra arguments to be passed to __new__ when unpickling.

import cPickle as pickle

pklfile = "test.pkl"

all_names = {}
class Name(object):
    def __new__(cls, c, s="", v=""):
        name = "%s %s %s" % (c, s, v)
        if all_names.has_key(name):
            return all_names[name]
        else:
            self = all_names[name] = object.__new__(cls)
            self.c, self.s, self.v = c, s, v

        return self

    def __getnewargs__(self):
        return (Name.__repr__(self),)

    def __repr__(self):
        return '<Name %r, %r, %r>' % (self.c, self.s, self.v)

    def __str__(self):
        return "%s %s %s" % (self.c, self.s, self.v)

with open(pklfile, 'wb') as output:
    pickle.dump(Name("hi"), output, pickle.HIGHEST_PROTOCOL)

with open(pklfile, 'rb') as input:
    name_obj = pickle.load(input)
    print name_obj