An instance of a custom class can work as a container for attributes you set on it. This can start trivially simple:
class MyContainer:
pass
a = MyContainer()
a.x = Foo()
a.y = Foo()
a.x.DoFoo()
You can make it a little more complicated to get the ability to pass in the attributes you want as part of the constructor (using the same semantics as the dict
constructor):
def MyContainer:
def __init__(self, vals={}, **kwvals):
self.__dict__.update(vals, **kwvals)
a = MyContainer({"x":Foo()}, y=Foo()) # there are multiple ways to pass the args
a.x.DoFoo()
If you don't need to add or remove values after you create a container of this sort, you can instead use the standard library's collections.namedtuple
class factory. You pass it a class name and a sequence of attribute names and it will return you a new class.
from collections import namedtuple
A = namedtuple("A", ["x", "y"])
a = A(Foo(), y=Foo()) # can use positional or keyword arguments
a.x.DoFoo() # this still works!
a.x = "something else" # but this will raise an error