def __new__(cls, classname, bases, classdict):
        """ Everything needs to be done in __new__, since type.__new__ is
            where __slots__ are taken into account.
        """
        import inspect

        # define as local functions the __init__ and __repr__ that we'll
        # use in the new class

        def __init__(self, **kw):
            """ Simplistic __init__: first set all attributes to default
                values, then override those explicitly passed in kw.
            """
            for k, (value, copy_op) in self.__defaults__.iteritems():
                if k not in kw: #No need to set value to be overridden later on.
                    if copy_op is None:
                        #No copy op (immutable value)
                        setattr(self, k, value)
                    else:
                        setattr(self, k, copy_op(value))
            for k, value in kw.iteritems():
                setattr(self, k, value)

        def __repr__(self):
            """ 
            repr operator.
            """
            rep = ['%s=%r' % (k, getattr(self, k))
                for k in sorted(self.__defaults__)]
            return '%s(%s)' % (classname, ', '.join(rep))


        def __eq__(self, other):
            '''Basic __eq__.
            '''
            if not isinstance(other, type(self)):
                return False
            for attr in self.__defaults__:
                if getattr(self, attr) != getattr(other, attr):
                    return False
            return True

        def __ne__(self, other):
            return not self == other

        # build the newdict that we'll use as class-dict for the new class
        newdict = dict(
            __slots__=classdict.pop('__slots__', []),
            __defaults__={},
            __init__=__init__,
            __repr__=__repr__,
            __eq__=__eq__,
            __ne__=__ne__,
        )

        # update the dafaults dict with the contents of the bases's defaults, so
        # they're properly initialized during __init__
        for base in bases:
            newdict['__defaults__'].update(getattr(base, '__defaults__', {}))


        for k, value in classdict.iteritems():
            if k.startswith('__') or inspect.isfunction(value) or \
                type(value) is property:
                # methods: copy to newdict
                newdict[k] = value
            else:
                # class variables, store name in __slots__ and name and
                # value as an item in __defaults__

                #Default for each value is deepcopy, but we may optimize that
                #(if the copy op is None, the value is considered immutable).
                copy_op = copy.deepcopy

                if value.__class__ in (
                    bool, int, float, long, str, NoneType
                    ):
                    copy_op = None
                else:
                    if value.__class__ in (tuple, frozenset):
                        if not value:
                            copy_op = None

                    if value.__class__ in (list, set, dict):
                        if not value:
                            copy_op = copy.copy


                newdict['__slots__'].append(k)
                newdict['__defaults__'][k] = (value, copy_op)

        # finally delegate the rest of the work to type.__new__
        return type.__new__(cls, classname, bases, newdict)
 Everything needs to be done in __new__, since type.__new__ is
            where __slots__ are taken into account.
        
recipes/Python/577999_Bunch_class_created_attributes/recipe-577999.py