I'd like to make a class that unpacks it's objects like a dictionary.
For example, with a dictionary you can do this
foo = {
  "a" : 1
  "b" : 2
}
def bar(a,b):
   return a + b
bar(**foo)
outputs 3
And I'd like to be able to do this
class FooClass:
    def __init__(self):
        self.a = a
        self.b = b
f = FooClass()
bar(**f)
and have it output 3
This is the most related question I could find but it doesn't address this so I'm thinking it might not be possible.
Currently what my solution would be this:
class FooClass:
    def __init__(self):
        self.a = a
        self.b = b
    def to_dict(self):
        return {
          "a" : self.a,
          "b" : self.b
        }
f = FooClass()
bar(**f.to_dict())
                As pointed out in the comments, writing a conformant subclass of the collections.abc.Mapping abstract class is the way to go. To (concretely) subclass this class, you need to implement __getitem__, __len__, and __iter__ to behave consistently like a dictionary would. So that means __getitem__ expects a string, __iter__ returns an iterable of strings, etc.
For a simple example, we'll simply delegate all of these to self.__dict__, but in real code you'd likely want to do something more refined.
from collections.abc import Mapping
class FooClass(Mapping):
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def __getitem__(self, x):
        return self.__dict__[x]
    def __iter__(self):
        return iter(self.__dict__)
    def __len__(self):
        return len(self.__dict__)
def bar(a, b):
    return a + b
foo = FooClass(40, 2)
print(bar(**foo))
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With