inheritance?

Discussion in 'Python' started by KraftDiner, Aug 16, 2006.

  1. KraftDiner

    KraftDiner Guest

    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?
     
    KraftDiner, Aug 16, 2006
    #1
    1. Advertising

  2. KraftDiner

    John Henry Guest

    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)

    KraftDiner wrote:
    > 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?
     
    John Henry, Aug 16, 2006
    #2
    1. Advertising

  3. On Tue, 15 Aug 2006 19:35:11 -0700, KraftDiner wrote:

    > 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?



    --
    Steven D'Aprano
     
    Steven D'Aprano, Aug 16, 2006
    #3
  4. KraftDiner

    KraftDiner Guest

    Steven D'Aprano wrote:
    > On Tue, 15 Aug 2006 19:35:11 -0700, KraftDiner wrote:
    >
    > > 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?


    >
    >
    > --
    > Steven D'Aprano
     
    KraftDiner, Aug 16, 2006
    #4
  5. KraftDiner

    infidel Guest

    > 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
     
    infidel, Aug 16, 2006
    #5
  6. KraftDiner

    John Henry Guest

    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.

    KraftDiner wrote:
    > Steven D'Aprano wrote:
    > > On Tue, 15 Aug 2006 19:35:11 -0700, KraftDiner wrote:
    > >
    > > > 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?
    >
    >
    > >
    > >
    > > --
    > > Steven D'Aprano
     
    John Henry, Aug 16, 2006
    #6
  7. KraftDiner

    KraftDiner Guest

    Steven D'Aprano wrote:
    > On Tue, 15 Aug 2006 19:35:11 -0700, KraftDiner wrote:
    >
    > > 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






    >
    > --
    > Steven D'Aprano
     
    KraftDiner, Aug 16, 2006
    #7
  8. KraftDiner

    Inyeol Lee Guest

    On Wed, Aug 16, 2006 at 11:07:08AM -0700, KraftDiner wrote:
    [...]
    > 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.
    >>> class baseClass:

    .... @staticmethod
    .... def fromfile(string):
    .... if string == "A":
    .... return typeA()
    .... else:
    .... return typeB()
    .... def getName(self):
    .... print self.name
    ....
    >>> class typeA(baseClass):

    .... def __init__(self):
    .... self.name = "A"
    .... print "typeA init"
    ....
    >>> class typeB(baseClass):

    .... def __init__(self):
    .... self.name = "B"
    .... print "typeB init"
    ....
    >>> a = baseClass.fromfile("A")

    typeA init
    >>> a.getName()

    A
    >>> b = baseClass.fromfile("B")

    typeB init
    >>> b.getName()
    >>> B
    >>>


    --
    Inyeol Lee
     
    Inyeol Lee, Aug 16, 2006
    #8
  9. KraftDiner

    John Henry Guest


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


    > >
    > > --
    > > Steven D'Aprano


    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.
     
    John Henry, Aug 16, 2006
    #9
  10. KraftDiner

    John Henry Guest

    Oops! Forgot to remove fromfile from baseClass. Wouldn't matter
    though.

    John Henry wrote:
    > > 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
    > >

    >
    > > >
    > > > --
    > > > Steven D'Aprano

    >
    > 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.
     
    John Henry, Aug 16, 2006
    #10
  11. 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.
     
    Bruno Desthuilliers, Aug 28, 2006
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. maxw_cc
    Replies:
    1
    Views:
    3,144
    Martijn van Steenbergen
    Dec 21, 2003
  2. cppsks
    Replies:
    0
    Views:
    827
    cppsks
    Oct 27, 2004
  3. karthikbalaguru
    Replies:
    9
    Views:
    1,041
  4. Daniel Pitts
    Replies:
    27
    Views:
    1,904
    Mike Schilling
    Feb 27, 2008
  5. johnsonlau
    Replies:
    1
    Views:
    777
    Kai-Uwe Bux
    Jul 21, 2008
Loading...

Share This Page