On Sep 23, 1:23 am, "Tom Harris" <[EMAIL PROTECTED]> wrote:
> Greetings, > > I want to have a class as a container for a bunch of symbolic names > for integers, eg: > > class Constants: > FOO = 1 > BAR = 2 > > Except that I would like to attach a docstring text to the constants, > so that help(Constants.FOO) will print some arbitrary string. Sort of > a very limited implementation of PEP 224. The only solution that I can > see is to subclass int.__new__(), since once I have an int all it's > attributes are immutable. Here's one approach, using metaclasses and descriptors; it sort of works, but it's less than ideal, both in usage and implementation. George #====== usage ============================================ class MyConstants: __metaclass__ = ConstantsMeta FOO = const(1, 'some docs about foo') BAR = const(2) print MyConstants.FOO.__doc__ help(MyConstants.FOO) print MyConstants.FOO - MyConstants.BAR print MyConstants.FOO - 2 print 1 - MyConstants.BAR #======= implementation =================================== def ConstantsMeta(name, bases, namespace): for name,attr in namespace.iteritems(): if isinstance(attr, const): namespace[name] = _ConstDescriptor(name, attr.value, attr.doc) return type(name, bases, namespace) class const(object): def __init__(self, value, doc=None): self.value = value self.doc = doc class _ConstDescriptor(object): def __init__(self, name, value, doc): cls = type(name, (), dict( __doc__ = doc, __add__ = lambda self,other: value+other, __sub__ = lambda self,other: value-other, # ... __radd__ = lambda self,other: other+value, __rsub__ = lambda self,other: other-value, # XXX lots of boilerplate code for all special methods follow... # XXX Is there a better way ? )) self._wrapper = cls() def __get__(self, obj, type): return self._wrapper -- http://mail.python.org/mailman/listinfo/python-list