Is this an OK design?

U

urnerk

Partly because I'm doing OpenOffice PowerPoint (not much room on a slide),
I'm breaking what could be a single class into a succession of tiny
"version" classes, each inheriting from the one before, and each adding
more functionality.

I'm also separating each version into a module of its own, such that each
successive version keeps the same name (say P), and inherits from module.P

Part of the goal is to demonstrate inheritance, so it's OK to evolve my P
class over several versions.

Here's a skeletal outline, where --- separates modules:

---- pv1.py ----

class P(object):
def __init__(self, amap)
self.amap = amap

--- pv2.py ---

import pv1
class P(pv1.P):

def __invert__(self):
# newmap = inverted self.amap
return P(newmap)

def __mul__(self,other): etc.

--- pv3.py ---

import pv2
class P(pv2.P):
def __div__(self,other):
return self * ~other

---

Note that only the base class has a constructor, while the subclasses add
additional methods.

The above design had a problem though:
True

The problem was __invert__, being defined in pv2, would return an instance
of pv2.P, which doesn't yet know about __div__ (that comes in the next
version).

So the need is to have methods that return a P, to return a P of the same
version, e.g. if p1 is of type pv3.P, then __invert__, even though defined
in the parent, should return a pv3.P when invoked.

My solution was:

---- pv1.py ----

class P(object):
def __init__(self, amap)
self.amap = amap
self.P = self.__class__ # <-- store type of instance

--- pv2.py ---

import pv1
class P(pv1.P):

def __invert__(self):
# newmap = inverted self.amap
return self.P(newmap) # <--- class is now object attribute

def __mul__(self,other): etc.

--- pv3.py ---

import pv2
class P(pv2.P):
def __div__(self,other):
return self * ~other

---

Now when I go:
True

i.e. q/p1 succeeds, because ~p1 returns a pv3.P type, which understands
about __div__.

What I'd like to know is: is my solution perverse or Pythonic? Is there a
better way?

Kirby
 
D

David Goodger

---- pv1.py ----

class P(object):
def __init__(self, amap)
self.amap = amap
self.P = self.__class__ # <-- store type of instance

--- pv2.py ---

import pv1
class P(pv1.P):

def __invert__(self):
# newmap = inverted self.amap
return self.P(newmap) # <--- class is now object attribute ....
What I'd like to know is: is my solution perverse or Pythonic?
Is there a better way?

Whenever I've had to do the same thing, I'd just say:

return self.__class__(newmap)

Or make a specialized method, like:

def new(self, *args):
return self.__class__(*args)

In other words, say it directly without the indirection of a class
attribute.

Unless, of course, you want to modify the attribute for some
reason. Even then, I'd change the name to be more
self-documenting.

-- David Goodger
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top