oo problem

James Stroud jstroud at mbi.ucla.edu
Sun Dec 10 07:42:44 EST 2006


Tool69 wrote:
> Hi,
> I've got a simple but difficult problem :
> 
> Suppose I've got a Paper class, on wich I can draw i.e a rectangle, a
> circle or whatever.
> 
> class Paper(...):
>     def __init__(self, paperx, papery):
>         self.paperx = paperx
>         self.papery = papery
>         ....
>     def draw(self, Primitive_Object):
>         ....
> class Rectangle(  ): <--- a Primitive_Object
>     ...
> 
> Now, inside my Rectangle class, I need to recover the Paper instance
> who called it (because I need the paper sizes to calculate something).
> I now I can use a global variable, say " _paper" and then, inside  my
> Paper.__init__() write something like this :
> 
> global _paper
> _paper = [paperx,papery]
> 
> But it has drawbacks : what if I've got several Paper instances ?
> 
> I don't know if I'm clear enought, 
> Thanks for your help :
> 6TooL9
> 

I think you may not be thinking about your problem in the most 
object-oriented way. For example, the Paper.draw() method will already 
have a reference to the "calling" Paper instance accessible via the name 
"self". E.g.:

class Paper(...
   def draw(self, primitive):
     do_something_with(self.paperx, self.papery)
     # etc

Now, if the draw() method were in the primitive and not the paper, then 
a reference to the paper should be kept in the primitive. But, as you 
will see below, this seems to make little sense (to me, at least).

If you find that you need to access the primitive's "parent" paper 
attributes from within the primitive, then you might want to check 
whether you have structured your code in the most sensible manner. 
Conceptually, children shouldn't be overly concerned with the workings 
of their parents, lest they be a bit too presumptuous and risk a good 
scolding.

The thought process I always go through is "why does this object need to 
have this particular reference?" Do primitives really need to know 
anything about the paper on which they are drawn?

I try not to make objects overly reflexive. For example, should a 
primitive really be drawing itself? Perhaps something else should bring 
a primitive into existence based on the attributes contained in a 
primitive's data structure and the properties of the medium in which or 
on which it will exist.

What if some creator had asked of you: "Embed Thyself unto the 3-D 
Manifold Known as the Universe." Your first requirement before any steps 
toward physical existence would, of course, be a reference to the 
Universe--so that you could see if you would actually fit.

Perhaps it would be better for a 3rd party to manage the process of 
person creation, like, say, a mother? Children would then not be 
required to ponder the extent of the Universe before their own physical 
manifestation and could focus on things more meaningful to themselves, 
like whether they are hungry or need to go potty.

By this thought process, I propose that it makes more sense to create a 
Drawing object that has references to both the primitives and the paper 
and then manage drawing through that object.

class Drawing(object):
   def __init__(self, paper, primitives):
     self._paper = paper
     self._primitives = primitives

my_primitives = [Square(5), Circle(10), DoubleEndedArrow(5,5,5,1,2,1,2)]
my_paper = Paper()
my_drawing = Drawing(my_paper, my_primitives)

Now the paper can just worry about its paper specific attributes (which 
might be its dimensions, border, bond weight, etc), the primitives can 
worry about primitive specific attributes (size, line-width, 
fill-color), and the drawing can manage everything required to make a 
drawing (paper, primitives, color model, etc.).

I think that this is the what you were getting at with your global 
"_paper" variable, except now "global" is the context of the Drawing class.

James




More information about the Python-list mailing list