0

There are several questions about pickling namedtuples already, however none of the ones I found [1] [2] [3] [4] deals with the case of pickling a namedtuple that is bound on an object instance. Consider the following example

import pickle
from collections import namedtuple


class TupleSplitter:
    r"""Splits a tuple into namedtuple, given by the groups."""

    def __init__(self, groups: dict[str, list[int]]):
        self.groups = groups
        self.group_type = namedtuple("Groups", groups)  # <-- How to replace this?

    def __call__(self, x: tuple) -> tuple:
        return self.group_type(
            **{key: tuple(x[k] for k in group) for key, group in self.groups.items()}
        )


encoder = TupleSplitter({"a": [0, 1, 2], "b": [2, 3, 4]})
encoder((1, 2, 3, 4, 5, 6))

pickle.dumps(encoder)  # <-- PicklingError: attribute lookup Groups on __main__ failed

Question: Is it possible to have pickle-able tuple-factories with attribute names only known at runtime?

NOTE: I am not interested in any answers suggesting using a dictionary here, the return value MUST be a subclass of tuple!

NOTE: I am not interested in any answers proposing using a dill, cloudpickle or anything of the like. It must work with plain pickle!

Hyperplane
  • 964
  • 1
  • 8
  • 25
  • You'd need to implement the pickling protocol, probably you can just monkey patch the class. You should be able to just implement `__reduce__`, see this related question: https://stackoverflow.com/questions/24657781/factory-method-pattern-conflicts-with-use-of-multiprocessing-queue – juanpa.arrivillaga Feb 21 '22 at 01:02
  • Although those answers seem convoluted... I'm on my phone right now I'll try to look at this later on my laptop. But check out the pickle docs: https://docs.python.org/3/library/pickle.html – juanpa.arrivillaga Feb 21 '22 at 01:08

0 Answers0