Adding an interface to existing classes

Terry Reedy tjreedy at udel.edu
Sat Dec 24 20:58:24 EST 2011


On 12/24/2011 6:49 PM, Spencer Pearson wrote:
> On Dec 23, 9:13 am, Terry Reedy<tjre... at udel.edu>  wrote:
>> On 12/22/2011 3:21 AM, Spencer Pearson wrote:
>>
>>> I'm writing a geometry package, with Points and Lines and Circles and
>>> so on, and eventually I want to be able to draw these things on the
>>> screen. I have two options so far for how to accomplish this, but
>>> neither of them sits quite right with me, and I'd like the opinion of
>>> comp.lang.python's wizened elders.
>>
>>> Option 1. Subclassing.
>>> The most Pythonic way would seem to be writing subclasses for the
>>> things I want to display, adding a ".draw(...)" method to each one,
>>> like this:

There are people who would advocate a Drawable base class with a virtual 
or abstract .draw method and that DrawablePoint, etc, inherit from 
Drawable and Point.

>>> Option 2. A "draw" function, with a function dictionary.
>>
>> Option 3? Add a draw method to existing classes, rather than subclassing?

> Thanks for the response! Do you mean something like this?
> class Point(GeometricObject):
>      def intersect(self, other):
>          ...

I am interpreting this to mean that you have a world coordinate system 
for instances that have location and size.

>      def union(self, other):
>          ...
>      def draw(self, ...):
>          ...

Yes. I would consider that Option 0, the default, unless you have good 
reason to choose another. I would certainly include it on a list of options.

> I'd like to avoid this, because... well, what I want is a geometry
> package, and it seems to me that whistles and bells like GUI support
> ought to be confined to subpackages. I'd look at this and think, "the
> rest of the Point class deals with fundamental geometric reality.
> What's this GUI method doing mixed in with my beautiful mathematical
> purity?"

By default, all Python objects have a text representation method. I do 
not see that giving all concrete geometric objects (with a location and 
size) a visual representation is much different. I would use drawing 
functions that accept the coordinates and distances of your geometry 
world and translate to low-level pixel functions for a particular gui 
system. I agree that your geometrical objects should not know about 
pixels, screens, windows, and aspect ratios.

 > Is this the wrong attitude to take?

It depends on *your* goal and values.

> Or did you mean this?
> In file "geometry/gui.py":
> def draw_point(point, ...):
>      ...
> Point.draw = draw_point
>
> I've never modified an existing class before, and I fear the
> unfamiliar. If that's what you meant... it's really an acceptable
> thing to do?

Yes, in my opinion. The advantage of this is putting all the draw 
methods together, and possibly having more than one one set. On the 
other hand, one needs to know the data attributes of each class to 
understand its draw method.

> It seems like somebody might see "some_point.draw(...)"
> and be confused by the method's absence in the Point class definition.

With either suboption, you should put an abstract .draw method in the 
GeometricObject base class.

I would look at various game, graph, geometry, and gui packages handle 
drawing for more ideas.

-- 
Terry Jan Reedy




More information about the Python-list mailing list