On Sep 26, 12:25 am, "Gabriel Genellina" <[EMAIL PROTECTED]> wrote: > En Tue, 25 Sep 2007 22:41:31 -0300,KenKuhlman<[EMAIL PROTECTED]> > escribi?: > > > Replying to myself in case someone finds this interesting. > > > Anyway, I took another shot at this with a little fresher mind, and it > > was quickly obvious that I was trying to force attributes to behave > > more like classes. It was a small step from there to creating a > > factory function to return instances of the appropriate class. I'm > > much happier with the result than either of the two previously posted > > kludges. > > Still there is something I don't understand on your design. You appear to > be always concerned about *class* attributes. *Instance* attributes are > far more comon, and usually they change their value many times. > ... > Gabriel Genellina
I've only cared about class attributes to this point because my needs have been simple. They may not always be, however, so I'll take a shot at your challenge (below). I've basically just added a base class that defines __setattr__ to the mix. Thanks for the replies! -Ken # A factory function for generating attributes that can be annotated. def attr(value, doc=None): base = type(value) if base == bool: # bool class can't be used as a base, so we make one that can. class MyBool(int): def __str__(self): return str(bool(self)) __repr__ = __str__ base = MyBool class FancyAttr(base): pass fa = FancyAttr(value) fa.__doc__ = doc return fa class AnnotatedAttrsBase(object): _sticky_docs = True #False def __setattr__(self, name, value): """ Make sure attributes are fancy, maintaining docs if they're sticky. """ if type(value).__name__ != 'FancyAttr': doc = None if self._sticky_docs and hasattr(self, name): doc = self.__dict__[name].__doc__ self.__dict__[name] = attr(value, doc) else: self.__dict__[name] = value class Animal(AnnotatedAttrsBase): can_fly = attr(value = False, doc = "no Animal can fly unless explicitly noted") lives = attr(value = 1, doc = "most Animals have a single life") def __init__(self, color, legs, favorite_food): self.color = attr(color, "every animal has a color") self.legs = attr(legs, "most animals have legs") self.favorite_food = favorite_food class Mammal(Animal): pass class Cat(Mammal): def __init__(self, color): Mammal.__init__(self, color=color, legs=4, favorite_food='mice') self.lives = attr(value = 7, doc = "a cat starts with 7 lives") class Mouse(Mammal): def __init__(self, color, personality): Mammal.__init__(self, color=color, legs=4, favorite_food='cheese') self.personality = personality class Bird(Animal): can_fly = True _sticky_docs = False def __init__(self, color): Animal.__init__(self, color=color, legs=2, favorite_food='seed') tweety = Bird('yellow') tweety.lives = 42 sylvester = Cat('black') tom = Cat('blue') jerry = Mouse('brown', 'nice') itchy = Mouse('blue', 'sadist') scratchy = Cat('black') scratchy.lives = attr(7**7, "or so...") print scratchy.color, scratchy.color.__doc__ print scratchy.lives, scratchy.lives.__doc__ print tweety.legs, tweety.legs.__doc__ print tweety.lives, tweety.lives.__doc__ -- http://mail.python.org/mailman/listinfo/python-list