Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #54407 > unrolled thread

Re: mutlifile inheritance problem

Started byPeter Cacioppi <peter.cacioppi@gmail.com>
First post2013-09-18 16:54 -0700
Last post2013-09-19 02:05 +0000
Articles 4 — 3 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: mutlifile inheritance problem Peter Cacioppi <peter.cacioppi@gmail.com> - 2013-09-18 16:54 -0700
    Re: mutlifile inheritance problem Peter Cacioppi <peter.cacioppi@gmail.com> - 2013-09-18 17:03 -0700
    Re: mutlifile inheritance problem Ned Batchelder <ned@nedbatchelder.com> - 2013-09-18 20:38 -0400
      Re: mutlifile inheritance problem Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-09-19 02:05 +0000

#54407 — Re: mutlifile inheritance problem

FromPeter Cacioppi <peter.cacioppi@gmail.com>
Date2013-09-18 16:54 -0700
SubjectRe: mutlifile inheritance problem
Message-ID<9043161b-e193-482a-a90c-42e8dfae978c@googlegroups.com>
This is a very old topic, but here is a trick for single inheritance. (The problem you allude to isn't restricted to multiple inheritance).

Any class with a single parent simply defines this function.


    def mySuper(self) : 
        return super(self.__class__, self)
      
And then any parent function be referenced like
    self.mySuper().foo()

This includes __init__.

You can read more here.

http://atlee.ca/blog/posts/blog20081121python-reload-danger-here-be-dragons.html


On Thursday, March 21, 2002 2:03:23 PM UTC-7, Marc wrote:
> I have classes defined in different files and would like to inherit
> from a class in file A.py for a class in file B.py but am running into
> problems.  I'm using Python 1.5.2 on Windows NT
> 
> Here's a specific example:
> 
> ************************
> file cbase01.py:
> 
> class CBase:
> 
>     def __init__(self):
>         self.cclass = None
>         print "cbase"
> 
> class CImStream(CBase):
> 
>     def __init(self):
>         CBase.__init__(self)
>         print "CImStream"
> 
> *************************
> in file wrappers_A01.py: 
> 
> import cbase01
> reload(cbase01)
> 
> class ImStream_SavedBitmaps(cbase01.CImStream):
> 
>     def __init__(self):
>         cbase.CImStream.__init__(self)
>         print "SavedBitmaps"
> 
> **************************
> in file sequencer01.py
> 
> import cbase01    # the offending lines, program works 
> reload(cbase01)   # if I comment these out.
> 
> class Sequencer:
> 
>     def Append(self, item):
>         pass
> 
> *****************************
> in test02.py
> 
> import wrappers_A01
> reload(wrappers_A01)
> 
> import sequencer01
> reload(sequencer01)
> 
> x0 = wrappers_A01.ImStream_SavedBitmaps()
> ***************************************************************
> 
> If I run test02 I get the traceback
> 
> Traceback (innermost last):
>   File "<string>", line 1, in ?
>   File "D:\PythonCode\pna\eyeTracking\tests\test02.py", line 15, in ?
>     x0 = wrappers_A01.ImStream_SavedBitmaps()
>   File "D:\PythonCode\pna\eyeTracking\tests\wrappers_A01.py", line 21,
> in __init__
>     cbase.CImStream.__init__(self)
> TypeError: unbound method must be called with class instance 1st
> argument
> 
> 
> Any ideas what I am doing wrong?
> 
> Thanks,
> Marc

[toc] | [next] | [standalone]


#54409

FromPeter Cacioppi <peter.cacioppi@gmail.com>
Date2013-09-18 17:03 -0700
Message-ID<6bea4bf3-d1a7-463a-8fca-0c90d4a28856@googlegroups.com>
In reply to#54407
One more comment - my trick has some utility with multiple inheritance, but you really need to understand super() to and method resolution ordering in that case (as, I suppose, you ought to whenever you cross the Rubicon beyond single inheritance). So it's a nice trick but YMMV

On Wednesday, September 18, 2013 4:54:00 PM UTC-7, Peter Cacioppi wrote:
> This is a very old topic, but here is a trick for single inheritance. (The problem you allude to isn't restricted to multiple inheritance).
> 
> 
> 
> Any class with a single parent simply defines this function.
> 
> 
> 
> 
> 
>     def mySuper(self) : 
> 
>         return super(self.__class__, self)
> 
>       
> 
> And then any parent function be referenced like
> 
>     self.mySuper().foo()
> 
> 
> 
> This includes __init__.
> 
> 
> 
> You can read more here.
> 
> 
> 
> http://atlee.ca/blog/posts/blog20081121python-reload-danger-here-be-dragons.html
> 
> 
> 
> 
> 
> On Thursday, March 21, 2002 2:03:23 PM UTC-7, Marc wrote:
> 
> > I have classes defined in different files and would like to inherit
> 
> > from a class in file A.py for a class in file B.py but am running into
> 
> > problems.  I'm using Python 1.5.2 on Windows NT
> 
> > 
> 
> > Here's a specific example:
> 
> > 
> 
> > ************************
> 
> > file cbase01.py:
> 
> > 
> 
> > class CBase:
> 
> > 
> 
> >     def __init__(self):
> 
> >         self.cclass = None
> 
> >         print "cbase"
> 
> > 
> 
> > class CImStream(CBase):
> 
> > 
> 
> >     def __init(self):
> 
> >         CBase.__init__(self)
> 
> >         print "CImStream"
> 
> > 
> 
> > *************************
> 
> > in file wrappers_A01.py: 
> 
> > 
> 
> > import cbase01
> 
> > reload(cbase01)
> 
> > 
> 
> > class ImStream_SavedBitmaps(cbase01.CImStream):
> 
> > 
> 
> >     def __init__(self):
> 
> >         cbase.CImStream.__init__(self)
> 
> >         print "SavedBitmaps"
> 
> > 
> 
> > **************************
> 
> > in file sequencer01.py
> 
> > 
> 
> > import cbase01    # the offending lines, program works 
> 
> > reload(cbase01)   # if I comment these out.
> 
> > 
> 
> > class Sequencer:
> 
> > 
> 
> >     def Append(self, item):
> 
> >         pass
> 
> > 
> 
> > *****************************
> 
> > in test02.py
> 
> > 
> 
> > import wrappers_A01
> 
> > reload(wrappers_A01)
> 
> > 
> 
> > import sequencer01
> 
> > reload(sequencer01)
> 
> > 
> 
> > x0 = wrappers_A01.ImStream_SavedBitmaps()
> 
> > ***************************************************************
> 
> > 
> 
> > If I run test02 I get the traceback
> 
> > 
> 
> > Traceback (innermost last):
> 
> >   File "<string>", line 1, in ?
> 
> >   File "D:\PythonCode\pna\eyeTracking\tests\test02.py", line 15, in ?
> 
> >     x0 = wrappers_A01.ImStream_SavedBitmaps()
> 
> >   File "D:\PythonCode\pna\eyeTracking\tests\wrappers_A01.py", line 21,
> 
> > in __init__
> 
> >     cbase.CImStream.__init__(self)
> 
> > TypeError: unbound method must be called with class instance 1st
> 
> > argument
> 
> > 
> 
> > 
> 
> > Any ideas what I am doing wrong?
> 
> > 
> 
> > Thanks,
> 
> > Marc

[toc] | [prev] | [next] | [standalone]


#54410

FromNed Batchelder <ned@nedbatchelder.com>
Date2013-09-18 20:38 -0400
Message-ID<mailman.143.1379551101.18130.python-list@python.org>
In reply to#54407
On 9/18/13 7:54 PM, Peter Cacioppi wrote:
> This is a very old topic, but here is a trick for single inheritance. (The problem you allude to isn't restricted to multiple inheritance).
>
> Any class with a single parent simply defines this function.
>
>
>      def mySuper(self) :
>          return super(self.__class__, self)
>        
> And then any parent function be referenced like
>      self.mySuper().foo()

You can't use self.__class__ for super, it won't give you the right 
class if you are using subclasses:

     class MyBase(object):
         def mySuper(self):
             return super(self.__class__, self)

         def say(self):
             print "This is MyBase!"


     class Thing(MyBase):
         def say_it(self):
             print "The parent:"
             self.mySuper().say()

         def say(self):
             print "this is Thing!"

     class SubThing(Thing):
         pass

     thing = Thing()
     thing.say_it()

     sub = SubThing()
     sub.say_it()

This produces:

     The parent:
     This is MyBase!
     The parent:
     this is Thing!

super() takes a class and an instance for a reason. If you could use 
self.__class__ for the class, then it would only take the instance. 
Super() needs to know the instance, but also needs to know the class 
it's being called from.

--Ned.

> This includes __init__.
>
> You can read more here.
>
> http://atlee.ca/blog/posts/blog20081121python-reload-danger-here-be-dragons.html
>
>
> On Thursday, March 21, 2002 2:03:23 PM UTC-7, Marc wrote:
>> I have classes defined in different files and would like to inherit
>> from a class in file A.py for a class in file B.py but am running into
>> problems.  I'm using Python 1.5.2 on Windows NT
>>
>> Here's a specific example:
>>
>> ************************
>> file cbase01.py:
>>
>> class CBase:
>>
>>      def __init__(self):
>>          self.cclass = None
>>          print "cbase"
>>
>> class CImStream(CBase):
>>
>>      def __init(self):
>>          CBase.__init__(self)
>>          print "CImStream"
>>
>> *************************
>> in file wrappers_A01.py:
>>
>> import cbase01
>> reload(cbase01)
>>
>> class ImStream_SavedBitmaps(cbase01.CImStream):
>>
>>      def __init__(self):
>>          cbase.CImStream.__init__(self)
>>          print "SavedBitmaps"
>>
>> **************************
>> in file sequencer01.py
>>
>> import cbase01    # the offending lines, program works
>> reload(cbase01)   # if I comment these out.
>>
>> class Sequencer:
>>
>>      def Append(self, item):
>>          pass
>>
>> *****************************
>> in test02.py
>>
>> import wrappers_A01
>> reload(wrappers_A01)
>>
>> import sequencer01
>> reload(sequencer01)
>>
>> x0 = wrappers_A01.ImStream_SavedBitmaps()
>> ***************************************************************
>>
>> If I run test02 I get the traceback
>>
>> Traceback (innermost last):
>>    File "<string>", line 1, in ?
>>    File "D:\PythonCode\pna\eyeTracking\tests\test02.py", line 15, in ?
>>      x0 = wrappers_A01.ImStream_SavedBitmaps()
>>    File "D:\PythonCode\pna\eyeTracking\tests\wrappers_A01.py", line 21,
>> in __init__
>>      cbase.CImStream.__init__(self)
>> TypeError: unbound method must be called with class instance 1st
>> argument
>>
>>
>> Any ideas what I am doing wrong?
>>
>> Thanks,
>> Marc

[toc] | [prev] | [next] | [standalone]


#54411

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-09-19 02:05 +0000
Message-ID<523a5be6$0$29988$c3e8da3$5496439d@news.astraweb.com>
In reply to#54410
On Wed, 18 Sep 2013 20:38:10 -0400, Ned Batchelder wrote:

> super() takes a class and an instance for a reason. If you could use
> self.__class__ for the class, then it would only take the instance.
> Super() needs to know the instance, but also needs to know the class
> it's being called from.

You're correct, of course, but I would word the reason why slightly 
differently.

super needs to know which instance it is being called from, but it also 
needs to know which class the method is defined in. Hence, given:

class Spam(Food):
    def method(self):
        print("Spam spam spam!")
        super(Spam, self).method()

class PickledSpam(Spam):
    pass


obj = PickledSpam()
obj.method()

super is being called from a PickledSpam instance, self, but the call is 
defined in the Spam class. super needs to know about both of them.
        
Of course, this hinges on how one defines "called from". I think it is 
helpful to understand methods as being called from the instance doing the 
calling rather than the class where they are defined.


-- 
Steven

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web