Search code examples
pythonargument-unpackingpython-datamodel

What data model methods implement argument keyword unpacking?


I have a class that I would like to be able to unpack into an argument list using the *args and **kwargs syntax.

class MyFoo:
    x = 1
    y = 2 # unpack x and y
    z = 3 # do not unpack z

def bar(x, y):
    print(x, y)

def baz(a, b=2, x=100, y=100, z=5):
    print(a, b, x+2, y+2, z)

foo = MyFoo()

bar(*foo) # should print "1 2"
baz(1, **foo) # should print "1 2 3 4 5"

I can implement *foo by defining __iter__:

def __iter__(self):
    return iter([self.x, self.y])

However I haven't been able to figure out how to implement **foo. What methods need to be implemented to do this?


Solution

  • We just need to override keys to get the names of attributes to be unpacked, and then __getitem__ (preferably as a classmethod) to access their value. Check below:

    class MyFoo(object):
      x = 1
      y = 2 # unpack x and y
      z = 3 # do not unpack z
    
      def __iter__(self):
          return iter([self.x, self.y])
    
      def keys(self):
          return ['x', 'y']
    
      @classmethod
      def __getitem__(cls, key):
        return cls.__dict__[key]
    
    
    
    def bar(x, y):
      print(x, y)
    
    def baz(a, b=2, x=100, y=100, z=5):
      print(a, b, x+2, y+2, z)
    
    foo = MyFoo()
    
    bar(*foo) # should print "1 2"
    baz(1, **foo) # should print "1 2 3 4 5"