inheritance?

K

KraftDiner

I have two classes:

class implicitClass:
def __init__(self):
def isIVR(self): #This is a class private method.
def fromfile(self, fileObj, byteOrder):
def getVR(self):
def getGroup(self):
def getElement(self):
def getSize(self):
def getData(self):

class explicitClass:
def __init__(self):
def fromfile(self, fileObj):
def getVR(self):
def getGroup(self):
def getElement(self):
def getSize(self):
def getData(self):


As you can see the interface is almost identical.

How can I define a base class that will abstract
the type such that I don't know if its really and inplicit
or explicit object?
 
J

John Henry

Is this what you're looking for?

class baseClass:
def __init__(self):
def fromfile(self, fileObj, byteOrder=None):
def getVR(self):
def getGroup(self):
def getElement(self):
def getSize(self):
def getData(self):

class implicitClass(baseClass):
def __init__(self):
baseClass.__init__(self)
def isIVR(self): #This is a class private method.

class explicitClass(baseClass):
def __init__(self):
baseClass.__init__(self)
 
S

Steven D'Aprano

I have two classes:

class implicitClass:
def __init__(self):
def isIVR(self): #This is a class private method.

The convention is to flag classes as "private" with a leading underscore:

def _isIVR(self):

or double underscores for "really private, no, honestly":

def __isIVR(self):

but google on "python name mangling" before using that.

[snip]
As you can see the interface is almost identical.

How can I define a base class that will abstract
the type such that I don't know if its really and inplicit
or explicit object?

Something like this?


class baseClass:
def __init__(self):
raise NotImplementedError("Don't instantiate the base class!")
def fromfile(self):
def getElement(self):
# etc.


class implicitClass(baseClass):
def __init__(self):
# code
def _isIVR(self):
# code
def fromfile(self, fileObj, byteOrder):
# code
# etc.

Now, you can define instance = implicitClass() or explicitClass(). When
you come to use instance, you don't need to know whether it is one or the
other. If you need to type-test, call "isinstance(instance, baseClass)".

The only minor issue is that the fromfile method has a different
interface. If you really want to do duck typing, they need to have the
same interface. That might be as simple as:

class explicitClass(baseClass):
def fromfile(self, fileObj, byteOrder=None):
# byteOrder is ignored; it is included only for
# compatibility with implicitClass


Is that what you're asking for?
 
K

KraftDiner

Steven said:
I have two classes:

class implicitClass:
def __init__(self):
def isIVR(self): #This is a class private method.

The convention is to flag classes as "private" with a leading underscore:

def _isIVR(self):

or double underscores for "really private, no, honestly":

def __isIVR(self):

but google on "python name mangling" before using that.

[snip]
As you can see the interface is almost identical.

How can I define a base class that will abstract
the type such that I don't know if its really and inplicit
or explicit object?

Something like this?


class baseClass:
def __init__(self):
raise NotImplementedError("Don't instantiate the base class!")
def fromfile(self):
def getElement(self):
# etc.


class implicitClass(baseClass):
def __init__(self):
# code
def _isIVR(self):
# code
def fromfile(self, fileObj, byteOrder):
# code
# etc.

Now, you can define instance = implicitClass() or explicitClass(). When
you come to use instance, you don't need to know whether it is one or the
other. If you need to type-test, call "isinstance(instance, baseClass)".

The only minor issue is that the fromfile method has a different
interface. If you really want to do duck typing, they need to have the
same interface. That might be as simple as:

class explicitClass(baseClass):
def fromfile(self, fileObj, byteOrder=None):
# byteOrder is ignored; it is included only for
# compatibility with implicitClass


Is that what you're asking for?
Yes I believe so but in fromfile I want to call the appropriate
method depending on the in a parameter in fromfile...
like:
class baseClass:
def fromfile(self, fileObj, byteOrder=None, explicit=False):
if explicit:
call fromfile of explicit class
else:
call fromfile of implicit class

How is that done?
 
I

infidel

Yes I believe so but in fromfile I want to call the appropriate
method depending on the in a parameter in fromfile...
like:
class baseClass:
def fromfile(self, fileObj, byteOrder=None, explicit=False):
if explicit:
call fromfile of explicit class
else:
call fromfile of implicit class

class baseClass:
def fromfile(self, fileObj, **kwargs):
raise NotImplementedError()

class implicitClass:
def fromfile(self, fileObj, **kwargs):
byteOrder = kwargs.get('byteOrder', None)
# do something

class explicitClass:
def fromfile(self, fileObj, **kwargs):
# do something
 
J

John Henry

As others pointed out already, this kind of "if then else"
determination of type is best avoided.

If it looks like a duck, quakes like a duck, must be a duck.
Steven said:
I have two classes:

class implicitClass:
def __init__(self):
def isIVR(self): #This is a class private method.

The convention is to flag classes as "private" with a leading underscore:

def _isIVR(self):

or double underscores for "really private, no, honestly":

def __isIVR(self):

but google on "python name mangling" before using that.

[snip]
As you can see the interface is almost identical.

How can I define a base class that will abstract
the type such that I don't know if its really and inplicit
or explicit object?

Something like this?


class baseClass:
def __init__(self):
raise NotImplementedError("Don't instantiate the base class!")
def fromfile(self):
def getElement(self):
# etc.


class implicitClass(baseClass):
def __init__(self):
# code
def _isIVR(self):
# code
def fromfile(self, fileObj, byteOrder):
# code
# etc.

Now, you can define instance = implicitClass() or explicitClass(). When
you come to use instance, you don't need to know whether it is one or the
other. If you need to type-test, call "isinstance(instance, baseClass)".

The only minor issue is that the fromfile method has a different
interface. If you really want to do duck typing, they need to have the
same interface. That might be as simple as:

class explicitClass(baseClass):
def fromfile(self, fileObj, byteOrder=None):
# byteOrder is ignored; it is included only for
# compatibility with implicitClass


Is that what you're asking for?
Yes I believe so but in fromfile I want to call the appropriate
method depending on the in a parameter in fromfile...
like:
class baseClass:
def fromfile(self, fileObj, byteOrder=None, explicit=False):
if explicit:
call fromfile of explicit class
else:
call fromfile of implicit class

How is that done?

 
K

KraftDiner

Steven said:
I have two classes:

class implicitClass:
def __init__(self):
def isIVR(self): #This is a class private method.

The convention is to flag classes as "private" with a leading underscore:

def _isIVR(self):

or double underscores for "really private, no, honestly":

def __isIVR(self):

but google on "python name mangling" before using that.

[snip]
As you can see the interface is almost identical.

How can I define a base class that will abstract
the type such that I don't know if its really and inplicit
or explicit object?

Something like this?


class baseClass:
def __init__(self):
raise NotImplementedError("Don't instantiate the base class!")
def fromfile(self):
def getElement(self):
# etc.


class implicitClass(baseClass):
def __init__(self):
# code
def _isIVR(self):
# code
def fromfile(self, fileObj, byteOrder):
# code
# etc.

Now, you can define instance = implicitClass() or explicitClass(). When
you come to use instance, you don't need to know whether it is one or the
other. If you need to type-test, call "isinstance(instance, baseClass)".

The only minor issue is that the fromfile method has a different
interface. If you really want to do duck typing, they need to have the
same interface. That might be as simple as:

class explicitClass(baseClass):
def fromfile(self, fileObj, byteOrder=None):
# byteOrder is ignored; it is included only for
# compatibility with implicitClass


Is that what you're asking for?
Here I tried this example and maybe this will explain the difficulties
I'm having.
1) at the time the baseClass is constructed shouldn't the constructor
of the appropriate
type be called.
2) getName is doing nothing...

class baseClass:
def __init__(self):
pass
def fromfile(self, str):
if (str == 'A'):
a = typeA()
else:
a = typeB()
def getName(self):
pass

class typeA(baseClass):
def __init__(self):
self.name='A'
print 'typeA init'
def fromfile(self, str=None):
print 'typeA fromfile'
def getName(self):
print self.name

class typeB(baseClass):
def __init__(self):
self.name='B'
print 'typeB init'
def fromfile(self, str=None):
print 'typeB fromfile'
def getName(self):
print self.name

bc = baseClass()
bc.fromfile('A')
bc.getName()
bc.fromfile('B')
bc.getName()
bc.getName()

log:
typeA init
typeB init
 
I

Inyeol Lee

]
Here I tried this example and maybe this will explain the difficulties
I'm having.
1) at the time the baseClass is constructed shouldn't the constructor
of the appropriate
type be called.
2) getName is doing nothing...

class baseClass:
def __init__(self):
pass
def fromfile(self, str):
if (str == 'A'):
a = typeA()
else:
a = typeB()
def getName(self):
pass

class typeA(baseClass):
def __init__(self):
self.name='A'
print 'typeA init'
def fromfile(self, str=None):
print 'typeA fromfile'
def getName(self):
print self.name

class typeB(baseClass):
def __init__(self):
self.name='B'
print 'typeB init'
def fromfile(self, str=None):
print 'typeB fromfile'
def getName(self):
print self.name

bc = baseClass()
bc.fromfile('A')
bc.getName()
bc.fromfile('B')
bc.getName()
bc.getName()

log:
typeA init
typeB init


I didn't follow up this thread from the begining, but I think this is
what you want;

Python 2.4.3 (#1, Mar 31 2006, 09:09:53)
[GCC 2.95.3 20010315 (release)] on sunos5
Type "help", "copyright", "credits" or "license" for more information..... @staticmethod
.... def fromfile(string):
.... if string == "A":
.... return typeA()
.... else:
.... return typeB()
.... def getName(self):
.... print self.name
.... .... def __init__(self):
.... self.name = "A"
.... print "typeA init"
.... .... def __init__(self):
.... self.name = "B"
.... print "typeB init"
....
 
J

John Henry

Here I tried this example and maybe this will explain the difficulties
I'm having.
1) at the time the baseClass is constructed shouldn't the constructor
of the appropriate
type be called.

Not automatically.
2) getName is doing nothing...

class baseClass:
def __init__(self):
pass
def fromfile(self, str):
if (str == 'A'):
a = typeA()
else:
a = typeB()
def getName(self):
pass

class typeA(baseClass):
def __init__(self):
self.name='A'
print 'typeA init'
def fromfile(self, str=None):
print 'typeA fromfile'
def getName(self):
print self.name

class typeB(baseClass):
def __init__(self):
self.name='B'
print 'typeB init'
def fromfile(self, str=None):
print 'typeB fromfile'
def getName(self):
print self.name

bc = baseClass()
bc.fromfile('A')
bc.getName()
bc.fromfile('B')
bc.getName()
bc.getName()

log:
typeA init
typeB init

Maybe this would help:

class baseClass:
def __init__(self, name):
self.name=name
print 'type'+self.name+' init'
def fromfile(self, str):
if (str == 'A'):
a = typeA()
else:
a = typeB()
def getName(self):
print self.name

class typeA(baseClass):
def __init__(self):
baseClass.__init__(self, "A")
def fromfile(self, str=None):
print 'type'+self.name+' fromfile'

class typeB(baseClass):
def __init__(self):
baseClass.__init__(self, "B")
def fromfile(self, str=None):
print 'type'+self.name+' fromfile'

bcA = typeA()
bcA.fromfile()
bcA.getName()

bcB = typeB()
bcB.fromfile()
bc.getName()

I think you're looking at objects in an inverted way.

typeA is a kind of baseClass, and so is typeB.

not:

baseClass consists of 2 subclasses A and B.
 
B

Bruno Desthuilliers

KraftDiner a écrit :

(snip)
Here I tried this example and maybe this will explain the difficulties
I'm having.
1) at the time the baseClass is constructed shouldn't the constructor
of the appropriate type be called.

It is. But neither the constructor nor 'the appropriate type' are what
you think they are.
2) getName is doing nothing...

Of course. It's body is a 'pass' statement, which in Python means 'do
nothing'.
class baseClass:
def __init__(self):
pass

This initializer is useless.
def fromfile(self, str):
if (str == 'A'):
a = typeA()
else:
a = typeB()

And then the method returns and the object bound to the local name 'a'
is garbage-collected.

def getName(self):
pass

class typeA(baseClass):
def __init__(self):
self.name='A'
print 'typeA init'
def fromfile(self, str=None):
print 'typeA fromfile'

This method is not called by your code
def getName(self):
print self.name

This method is not called by your code

class typeB(baseClass):
def __init__(self):
self.name='B'
print 'typeB init'
def fromfile(self, str=None):
print 'typeB fromfile'

This method is not called by your code
def getName(self):
print self.name

This method is not called by your code

bc = baseClass()

creates an instance of baseClass and bind it to the name bc
bc.fromfile('A')

calls the fromfile method of class baseClass with (object bound to) bc
as first param and 'A' as second param. This methods creates an instance
of typeA, bind it to the local name 'a', and then returns.
bc.getName()

calls the getName method of class baseClass, which body is a 'pass'
statement.
bc.fromfile('B')

calls the fromfile method of class baseClass with (object bound to) bc
as first param and 'B' as second param. This methods creates an instance
of typeB, bind it to the local name 'a', and then returns.

bc.getName()
calls the getName method of class baseClass, which body is a 'pass'
statement.
bc.getName()
calls the getName method of class baseClass, which body is a 'pass'
statement.


See John Henry's answer for a correct implementation.
 

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

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top