object inheritance and default values

Ron Adam rrr at ronadam.com
Fri Oct 14 17:32:05 EDT 2005


George Sakkis wrote:
> "Ron Adam" <rrr at ronadam.com> wrote:
> 
> 
>>I'm trying to implement simple svg style colored complex objects in
>>tkinter and want to be able to inherit default values from other
>>previously defined objects.
>>
>>I want to something roughly similar to ...
>>
>>    class shape(object):
>>         def __init__(self, **kwds):
>>              # set a bunch of general defaults here.
>>              self.__dict__.update(kwds)
>>def draw(self, x=0, y=0, scale=1.0):
>>              # draw the object
>>
>>    hello = shape(text='hello')
>>    redhello = hello(color='red')
>>    largeredhello = redhello(size=100)
>>    largeredhiya = largeredhello(text='Hiya!')
>>    largeredhiya.draw(c, 20, 50)
>>
>>
>>I think this will need to require __new__ or some other way to do it.
>>But I'm not use how to get this kind of behavior.  Maybe the simplest
>>way is to call a method.
>>
>>    redhello = hello.makenew( color='red' )
> 
> 
> Just name it '__call__' instead of makenew and you have the syntax sugar you want:
> 
>     def __call__(self, **kwds):
>         new = self.__class__(**self.__dict__)
>         new.__dict__.update(kwds)
>         return new
> 
> Personally I would prefer an explicit method name, e.g. 'copy'; hiding the fact that 'shape' is a
> class while the rest are instances is likely to cause more trouble than it's worth.
> 
> George

Just got it to work with __call__ as a matter of fact.  ;-)

     def __call__(self,**kwds):
         for key in self.__dict__:
             if key not in kwds:
                 kwds[key] = self.__dict__[key]
         return shape(**kwds)

The purpose having the objects not call the methods explicityly in this 
case is to simplify the data structure in a way that it doesn't care. 
The point is to create as much consistancy in the data structure as 
possible without having to special case some objects as base objects, 
and some as instances.

     # Triangle
     triangle = shape( obj='regpolygon',
                       points=getrpoly(3),
                       fill='grey',
                       size=75
                       )

     # Text
     text = shape( obj='text', fill='black', size=10 )

     # CAUTION ICON
     caution = group( triangle(x=6, y=5),
                      triangle(fill='yellow'),
                      text( text='!',
                            x=39, y=32, size=35,
                            font='times', style='bold' )
                      )

I can use a shape() in the group exactly like triangle(), or text(). 
They are all the same thing to group. It's just a matter of what the 
defaults are.  This keeps things very simple.  ;-)

Then when it needs to be drawn...

     caution.draw(canvas, x, y, scale)

I still need to work on reusing and nesting groups and having them set 
default values. Maybe I need to make group a sub shape which contains a 
list of shapes, etc...

This is another work it out as I go project. ;-)

Cheers,
    Ron


























More information about the Python-list mailing list