Best way to do attribute docstrings?
Ken Kuhlman
kskuhlman at gmail.com
Wed Sep 26 23:26:32 EDT 2007
On Sep 26, 12:25 am, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
wrote:
> En Tue, 25 Sep 2007 22:41:31 -0300,KenKuhlman<kskuhl... at gmail.com>
> 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__
More information about the Python-list
mailing list