autoreload and package causing TypeError: super(type, obj): obj must be an instance or subtype of type

纵然是瞬间 提交于 2020-05-10 07:26:27

问题


I have python code spanning several files which I packaged up for convenience, ending up with the following 3 files under my_package directory:

__init__.py

contents:

from file1 import *
from file2 import *

file1.py contents:

class Base(object):
    pass

file2.py contents:

from file1 import Base 
class Derived(Base):
    def __init__(self):
        return super(Derived, self).__init__()

I then execute in IPython:

>>>%autoreload 2
>>>import my_package
>>>t = my_package.Derived()

So far so good. But then I make changes to file2.py, say adding a dummy attribute. Now when I execute:

>>>t = my_package.Derived()
>>>      2 class Derived(Base):
>>>      3     def __init__(self):
>>>----> 4         return super(Derived, self).__init__()
>>>      5 
>>>      6 dumm = 'asdf'
>>>
>>>TypeError: super(type, obj): obj must be an instance or subtype of type

This doesn't go away until I restart the IPython console. Why doesn't autoreload take care of this correctly? Everything works if I put Base and Derived into a single module file rather than package.


回答1:


I'm not a user of IPython, so I can't say exactly what's happening, but I guess that this is a symptom of using from file2 import * in your __init__.py file.

When you're creating an instance of your Derived class using package.Derived, you're not getting the most recent version of the class, but the old version that was current when the package was first loaded and the from file2 import * statement was run. When you modified the module code and IPython reloaded it, that changed package.file2.Derived, but not package.Derived.

However, the old version of the class still has a reference to its module's namespace, and when it tries to look itself up by name in the super call, it finds the newer version of the class instead. This is why you get an error, as the two Derived classes are not the same.

You would probably avoid this issue if you accessed package.file2.Derived directly. That will always get you to the current version of the class which shouldn't have any issues with super calls. Note that if there are still instances of the class that were created before you modified the module, you may still have issues (but that's probably not very surprising).




回答2:


In Python 3, using the new super().__init__() instead of super(Derived, self).__init__() solved the problem for me



来源:https://stackoverflow.com/questions/32481508/autoreload-and-package-causing-typeerror-supertype-obj-obj-must-be-an-insta

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!