[Tutor] Set/get doc strings of ALL attributes?
Gonçalo Rodrigues
op73418 at mail.telepac.pt
Wed Nov 17 13:52:36 CET 2004
pan at uchicago.edu wrote:
> Hi there,
>
> I've been wondering if there's a way to set/get doc string
> for ALL elements of a class (but not just the __doc__ of
> function/method).
>
No. Imagine the following:
>>> class Test(object):
... clsAttrib = 1
...
>>>
>>> Test
<class '__main__.Test'>
>>> Test.clsAttrib
1
clsAttrib is simply an attribute with no attached __doc__. If you do
want to attach docstring to simple attributes you have to "wrap" the
attribute in what is called a descriptor.
> I ended writing a class BaseObject for this purpose. It stores doc
> strings of variables (that is, the <name> that is assigned to a
> class using myclass.name). When asking for all docs, doc strings
> are collected from 3 different sources:
>
> 1) property __doc__;
> 2) the variables mentioned above;
> 3) function/method __doc__;
>
> It seems to work well. My questions:
>
> A) Will the above approach be able to cover all elements
> such that an automatic documentation mechinsm can be
> programmed?
>
Yes.
> B) Is there any other better way to do this?
>
Yes -- see below.
> C) I intend to use this class as the base class for all
> other subclass. Will this kind of design cause any problem
> in any class inherited from it?
>
Yes, because you do *not* want inheritance here -- see below.
> Thx in advance.
> pan
>
I have not tested your code, but I think it is not going to work,
because there are (at least) two problems with it. Warning: we are
dangerously entering metaclass programming, so I'm just going to go
ahead without too many explanations. If you can't follow me just holler.
>
> Here's the code:
>
> class BaseObject(object):
This is the first problem. Think about what you want to do: you want to
control the setting of elements in *the class*. If you want to control
the setting of attributes in an instance of some class you override
__setattr__ of *the class*, in this case, the class of a class, so what
you want is a *metaclass*. So it should be:
class MetaCls(type):
You have to alter some stuff below because of this, I'll leave that for
now and jump to the second main problem.
> '''An extention of class object, have the capacity of storing/retrieving
> doc string for variables. Doc strings are retrievd from 3 different
> elements: variable (name), property, and method (or function). See
> the code in getDoc() for how to retrieve them.
> '''
> def __init__(self):
> object.__init__(self)
> self.__docs__ ={'__docs__':'An internal dict storing doc'
> ' string of variables. Write: setattr(name, val, doc) or'
> ' setDoc(name, doc), read: getDoc(name) or getDocs().'
> ' Defined in class BaseObject.'}
>
> def setattr(self, name, val, doc=None):
> '''setattr(name, val, doc=None): set value and doc string
> of a variable <name>. If doc=None, doc is not changed
> Defined in class BaseObject.'''
>
> if doc!=None: self.__docs__[name] = doc
> self.__setattr__(name,val)
> return self
>
This is the second problem: When you're doing an assignment as
cls.attribute = value
this ends up calling
cls.__class__.__setattr__(name, val)
Note the signature: the default value is never passed so the above will
never work. What you want here is to *wrap* the attribute in a
descriptor so that it can gain a docstring. Check the docs for a primer
on descriptors. After it, if you have any doubts just holler.
Note: This is already advanced stuff, so you may want to go at
comp.lang.python for further help.
With my best regards,
G. Rodrigues
More information about the Tutor
mailing list