0

I want to bind a dynamically created namedtuple to a class

  1. When an instance of the class is initialized, a new namedtuple-type is created, and registered in globals() (this allows pickling).

  2. When the instance is deleted, I want to perform cleanup of the registration in globals().

I already have working code for this:

from collections import namedtuple

class ClassWithTuple:
    tuple_id: str
    tuple_type: type[tuple]

    def __init__(self, name: str, fields: list[str]) -> None:
        self.tuple_type = namedtuple(name, fields)
        self.tuple_id = f"_{name}_{self.__class__.__name__}_{hash(self)}"
        self.tuple_type.__qualname__ = self.tuple_id

        if self.tuple_id in globals():
            raise RuntimeError(f"A class '{self.tuple_id}' exists!")
        globals()[self.tuple_id] = self.tuple_id

    def __del__(self):
        del globals()[self.tuple_id]
        del self

obj = ClassWithTuple("FooTuple", ["a", "b", "c"])
obj.tuple_type(1, 2, 3)

What I'd like to do is refactor this in the form

class ClassWithTuple
    tuple_id: str
    tuple_type: type[tuple]

    def __init__(self, name: str, fields: list[str]) -> None:
        register_tuple(self, name, fields)

or possibly self.tuple_id, self.tuple_type = register_tuple(self, name, fields).

How can I automagically add the required __del__ cleanup code? (Especially, if the class defined __del__, then del globals()[self.tuple_id] should be prepended I suppose.)

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
Hyperplane
  • 1,422
  • 1
  • 14
  • 28
  • 3
    `__del__` should rarely (if ever) be used for cleanup; use a context manager instead. – chepner Sep 16 '22 at 19:15
  • @chepner Can you expand on that? Where would I put the context manager? Again the behaviour I want is that if the instance is deleted, the attached tuple class is deleted as well, and all the responsible code should ideally be hidden in the `register_tuple` call. – Hyperplane Sep 16 '22 at 19:45

0 Answers0