我有几个文件的python代码,为方便起见,我打包了这些文件,最后是my_package目录下的以下3个文件:
__init__.py
内容:
from file1 import *
from file2 import *
file1.py内容:
class Base(object):
pass
file2.py内容:
from file1 import Base
class Derived(Base):
def __init__(self):
return super(Derived, self).__init__()
然后我在IPython中执行:
>>>%autoreload 2
>>>import my_package
>>>t = my_package.Derived()
到目前为止一切顺利。 但后来我对file2.py进行了更改,比如说添加了一个虚拟属性。 现在当我执行:
>>>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
在我重新启动IPython控制台之前,这并没有消失。为什么不进行自动重载正确处理?如果我将Base和Derived放入单个模块文件而不是包中,那么一切都有效。
答案 0 :(得分:11)
我不是IPython的用户,所以我不能确切地说出发生了什么,但我想这是在from file2 import *
文件中使用__init__.py
的症状。
当您使用Derived
创建package.Derived
课程的实例时,您没有获得该课程的最新版本,但是该软件包是第一个时的旧版本加载并运行from file2 import *
语句。当您修改模块代码并重新加载IPython时,它改变了package.file2.Derived
,但没有改变package.Derived
。
但是,该类的旧版本仍然具有对其模块命名空间的引用,并且当它试图在super
调用中按名称查找自己时,它会找到该类的较新版本。这就是您收到错误的原因,因为两个Derived
类不相同。
如果您直接访问package.file2.Derived
,则可能会避免此问题。这将始终让您进入该类的当前版本,该版本不应该与super
调用有任何问题。请注意,如果在修改模块之前仍然存在该类的实例,则可能仍然存在问题(但这可能不是很令人惊讶)。
答案 1 :(得分:2)
在Python 3中,使用新的super().__init__()
代替super(Derived, self).__init__()
为我解决了这个问题