TypeError in base class __init__ after reload

View: New views
2 Messages — Rating Filter:   Alert me  

TypeError in base class __init__ after reload

by Daniel Knierim :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello Pythonistas,

Running the script 'instantiate_and_reload.py' gives me the error
    TypeError: unbound method __init__() must be called with ParentClass instance as first argument (got ChildClass instance instead)

on the last call to ChildClass(), at line 23. The earlier calls don't trigger the error.

-- Begin file instantiate_and_reload.py:
from parentclass import ParentClass
from childclass import ChildClass
import parentclass, childclass


p = parentclass.ParentClass()
c = childclass.ChildClass()
p = ParentClass()
c = ChildClass()

reload(parentclass)

p = parentclass.ParentClass()
c = childclass.ChildClass()
p = ParentClass()
c = ChildClass()

reload(childclass)

p = parentclass.ParentClass()
c = childclass.ChildClass()
p = ParentClass()
c = ChildClass()

-- End of file instantiate_and_reload.py

-- Begin file parentclass.py:
class ParentClass(): #same result with new-style classes (subclassing object)
    def __init__(self):
        pass


if __name__ == '__main__':
    p = ParentClass()

-- End of file parentclass.py

-- Begin file childclass.py:
from parentclass import ParentClass
import parentclass


class ChildClass(ParentClass):
    def __init__(self):
        ParentClass.__init__(self)


if __name__ == '__main__':
    p = ParentClass()
    c = ChildClass()

    reload(parentclass)
   
    p = ParentClass()
    c = ChildClass()

-- End of file childclass.py

-- Beginning of captured command-line session:
D:\Programs\Python\Sandbox\SubclassInitChain>python childclass.py

D:\Programs\Python\Sandbox\SubclassInitChain>python parentclass.py

D:\Programs\Python\Sandbox\SubclassInitChain>python instantiate_and_reload.py
Traceback (most recent call last):
  File "instantiate_and_reload.py", line 23, in <module>
    c = ChildClass()
  File "D:\Programs\Python\Sandbox\SubclassInitChain\childclass.py", line 7, in __init__
    ParentClass.__init__(self)
TypeError: unbound method __init__() must be called with ParentClass instance as first argument (got ChildClass instance instead)

D:\Programs\Python\Sandbox\SubclassInitChain>python -V
Python 2.5.1

-- end of captured command-line session

I can't understand why the last call to ChildClass() triggers the error, when the earlier calls don't.

Can somebody explain to me what's going on?  or what I'm doing wrong?

Thanks
- Dan Knierim

_______________________________________________
Tutor maillist  -  Tutor@...
http://mail.python.org/mailman/listinfo/tutor

Re: TypeError in base class __init__ after reload

by Kent Johnson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Oops, sending to the list with this PS:
Google 'python reload' for discussion and workarounds.

Daniel Knierim wrote:
> Hello Pythonistas,
>
> Running the script 'instantiate_and_reload.py' gives me the error
>     TypeError: unbound method __init__() must be called with ParentClass instance as first argument (got ChildClass instance instead)

I haven't looked at your script closely enough to know exactly where the
  error is but there are some real problems with reloading modules when
you have references to objects in the module object. The module is
reloaded but the references are not automatically rebound to the new
module. In particular, names that are imported from the module will
still refer to the original module, and instances of classes from the
module will refer (via their __class__ attribute) to the original class.

The docs for reload() talk about this a little:
http://docs.python.org/lib/built-in-funcs.html#l2h-61

For example (using the cmd module just because it contains a class):
In [1]: from cmd import Cmd

Cmd is bound to the class object in the cmd module
In [2]: c=Cmd()

c is an instance of the original class

In [3]: import cmd
In [4]: cmd.Cmd is Cmd
Out[4]: True
In [5]: isinstance(c, cmd.Cmd)
Out[5]: True

cmd.Cmd, Cmd and c.__class__ all refer to the same class

In [6]: reload(cmd)
Out[6]: <module 'cmd' from
'/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/cmd.pyc'>
In [7]: isinstance(c, cmd.Cmd)
Out[7]: False

We now have a new class object bound to cmd.Cmd, it is not the same object!

In [8]: from cmd import Cmd
In [9]: c.__class__
Out[9]: <class cmd.Cmd at 0x10ac870>
In [10]: c.__class__ is Cmd
Out[10]: False

c.__class__ is still the old Cmd class

In [11]: Cmd is cmd.Cmd
Out[11]: True
In [12]: reload(cmd)
Out[12]: <module 'cmd' from
'/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/cmd.pyc'>
In [13]: Cmd is cmd.Cmd
Out[13]: False

Cmd itself has the same trouble.

Kent

_______________________________________________
Tutor maillist  -  Tutor@...
http://mail.python.org/mailman/listinfo/tutor