Warning: this is a snippet I wrote to play with metaclasses, the same function can be written in different ways (like this bunch recipe)

class BunchMeta(type):
    def __new__(cls, name, bases, new_attrs):
        def __create(*args):
            new_attrs["names"] = {}
            for n, i in enumerate(args):
                new_attrs["names"][i] = n
            return type(name, bases, new_attrs)
        return __create
 
class Bunch(list):
    __metaclass__ = BunchMeta
    def __init__(self, *args):
        list.__init__(self, args)
 
    def get(self, m):
        return self[self.names[m]]
 
    def __str__(self):
        return '(' + ', '.join(["%s:%s" % (str(name), str(d)) for name, d in
                       zip(self.names, self)]) + ')'

Note:

  • I used a dict for the names and a list for the bunch because I wanted to use the bunch like a dict but also like an ordered list (see *slave3 in the usage below)
  • I did not find how to set names in a class variable with type builtin

Usage:

HostBunch = Bunch("ip", "port")
slaves = [HostBunch("192.168.10.%d" % i, "8754") for i in range(100, 211)]
for i in slaves[:3]:
    print i
# print the fourth slave "ip"
print slaves[3].get("ip")
# print the fourth slave "port"
print slaves[3].get("port")
 
def strize(*args):
    return "%s:%s" % args
 
print strize(*slaves[3])

Outputs:

(ip:192.168.10.100, port:8754)
(ip:192.168.10.101, port:8754)
(ip:192.168.10.102, port:8754)
192.168.10.103
8754
192.168.10.103:8754