Concrete classes -- stylistic question

Ian Bicking ianb at colorstudy.com
Thu Oct 10 20:25:31 EDT 2002


On Thu, 2002-10-10 at 16:29, Alex Martelli wrote:
> Gerhard Häring wrote:
>         ...
> > Now who will come up with a neat example using metaclasses?
> 
> I borrowed Guido's time machine to post about that:
> 
> http://tinyurl.com/1wq1

I should really learn to understand what's going on with metaclasses,
but here's my attempt at similar functionality without metaclasses... 

# Use Required if you don't want an attribute to have a default
# (i.e., a value has to be given at instantiation)
class Required: pass

def bunchbuilder(className, **kw):
    
    class Bunch(object):

        __slots__ = kw.keys()
        __defaults = kw
        __name = className

        def __init__(self, **kw):
            for var in self.__slots__:
                if self.__defaults[var] is Required \
                   and not kw.has_key(var):
                    raise TypeError, "%s() did not provide required keyword argument %s" % (self.__name, var)
                if kw.has_key(var):
                    setattr(self, var, kw[var])
                    del kw[var]
                else:
                    setattr(self, var, self.__defaults[var])
            if kw:
                raise TypeError, "%s() got unexpected keyword argument %s" % (self.__name, kw.keys())

        def __repr__(self):
            names = [name for name in dir(self) if not name.startswith('__') and not name.startswith('_Bunch__')]
            names.sort()
            return "%s(%s)" % (self.__name,  ", ".join(
                ["%s=%s" % (name, repr(getattr(self, name))) for name in names]))

    return Bunch

# Example, create a Point class:
Point = bunchbuilder('Point', x=Required, y=Required, color='grey')
p = Point(x=4.3, y=0.3)
print p
p.x = 10







More information about the Python-list mailing list