By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
438,216 Members | 1,032 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 438,216 IT Pros & Developers. It's quick & easy.

object inheritance and default values

P: n/a

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' )

But I want to be able to have all the objects access alike?

Hmmm.. I think maybe if if don't ever access shape (or Shape) directly
in my data structure, then __new__ would work? So my first default
object should be an instance of shape with a __new__ method to create
more? Ok, off to try it. But any comments will be welcome.

Cheers,
Ron
Oct 14 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
"Ron Adam" <rr*@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
Oct 14 '05 #2

P: n/a

George Sakkis wrote:
"Ron Adam" <rr*@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


Symmetry can be achieved by making shape a factory function of Shape
objects while those Shape objects are factory functions of other Shape
objects by means of __call__:

def shape(**kwds):
class Shape(object):
def __init__(self,**kwds):
self.__dict__.update(kwds)

def __call__(self, **kwds):
new = self.__class__(**self.__dict__)
new.__dict__.update(kwds)
return new

return Shape(**kwds)

Kay

Oct 14 '05 #3

P: n/a
George Sakkis wrote:
"Ron Adam" <rr*@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







Oct 14 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.