[Tutor] __doc__ strings for attributes?

Kent Johnson kent37 at tds.net
Fri Nov 9 13:57:46 CET 2007


Wesley Brooks wrote:
> Dear Users,
> 
> How can I add information to an object to explain what it expects as
> it's attributes? For instance I may have an object that creates a CAD
> file based on a set of default values which are set by the __init__
> but can be altered before it runs. for example;
> 
> class MakeBasicShape:
>     def __init__(self):
>         self.boundsOptions = ['cuboid', 'cylinder', 'cad']
>         self.boundsInfo = ['cuboid', [0.,10.,0.,10.,0.,10.]']
> 
>     def MakeIt(self):
>         assert self.boundsInfo[0] in self.boundsOptions,
>                "Option not recognised: %s", self.boundsInfo[0]
>         if self.boundsInfo[0] == 'cuboid'
>             bounds = self.boundsInfo[1]
>             .... # code to make box
>         elif self.boundsInfo[0] == 'cylinder'
>             [height, radius, noSides] = self.boundsInfo[1]
>             .... # code to make cylinder
>         elif self.boundsInfo[0] == 'cad'
>             fileName = self.boundsInfo[1]
>             .... # code to load CAD file
>         return shape

I would write this as a factory function and use a dict as a lookup 
table to get the correct class to return:

assuming:
class Cuboid(object):
   # etc...

_makers = dict(cuboid=Cuboid, cylinder=Cylinder, cad=Cad)

def makeBasicShape(shape='cuboid', bounds=[0.,10.,0.,10.,0.,10.]):
   try:
     maker = _makers[shape]
   except KeyError:
     # Code to handle invalid shape option
   else:
     return maker(*bounds)

Kent

> 
> 
> if __name__ == '__main__':
>     shapeFactory0 = MakeBasicShape()
>     shape0 = shapeFactory.MakeIt() # a box
> 
>     shapeFactory1 = MakeBasicShape()
>     shapeFactory1.boundsInfo = ['cylinder' ,[20.,10.,36]]
>     shape1 = shapeFactory.MakeIt() # a cylinder
> 
>     shapeFactory2 = MakeBasicShape()
>     shapeFactory2.boundsInfo = ['cad' ,'/home/Wes/BigHand.stl']
>     shape2 = shapeFactory.MakeIt() # a CAD file
> 
> While this example could be coded with different functions for making
> a box, cylinder, and loading the CAD file I wanted to use attributes
> to control the object to simplify interaction with it from the user
> interface code. I would like to move away from getters and setters as
> they're taking up vast chunks of my code at the moment and do very
> little!

Simple getters and setters are not needed in Python. The flexibility 
they give in Java and C++ is provided by Python properties.

> Can I also stop new attributes being added to the MakeBasicShape class?

Yes, but it is rarely worth the trouble; Python culture tends to a 
philosophy of "we're all adults here" and doesn't try too hard to 
prevent programmers from shooting themselves in the foot.

The preferred way to do this IIRC is to define __setattr__ on your class 
and check for valid attribute names.

Kent


More information about the Tutor mailing list