1

I am trying to pickle the namedtuple like this:

def f():
    TemplateData = namedtuple('TemplateData', ['field1', 'field2'])
    f1 = np.random.randn(50,50)
    f2 = np.random.randn(50,50)
    td = TemplateData(f1, f2)
    return td

data = f()
with open("aaaa.pkl", "wb") as fl:
    pkl.dump(data, fl)

but this crashes due to error:

PicklingError: Can't pickle <class '__main__.TemplateData'>: it's not the same object as __main__.TemplateData

What's wrong? If pickle is not the best way to store named tuple - what is the most efficient way?

martineau
  • 99,260
  • 22
  • 139
  • 249
Ladenkov Vladislav
  • 1,076
  • 14
  • 36

1 Answers1

5

You need to define the namedtuple outside of your function, and change the name of your namedtuple to TemplateData.

TemplateData = namedtuple('TemplateData', ['field1', 'field2'])
f1 = np.random.randn(50,50)
f2 = np.random.randn(50,50)
model_cluster = TemplateData(f1, f2)

with open("aaaa.pkl", "wb") as fl:
    pkl.dump(model_clusters_dict, fl)
Batman
  • 7,346
  • 6
  • 34
  • 67
  • ahh, i get it, the class it tries to find class "TemplatedData" in my context, but can not, because the class is destroyed after the `f()` returns? – Ladenkov Vladislav Feb 23 '19 at 01:22
  • There's two things. One is that namedtuple isn't a class, it's a class factory that returns a class, which you in turn use to make instances. And the second is that pickle can't see the class definition if it's inside a function, because it's not in the global namespace. – Batman Feb 23 '19 at 01:41