autoreload and package causing TypeError: super(type, obj): obj must be an instance or subtype of type
autoreload and package causing TypeError: super(type, obj): obj must be an instance or subtype of type
我有 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 控制台之前,这不会消失。为什么 autoreload 不能正确处理这个问题?如果我将 Base 和 Derived 放入单个模块文件而不是包中,一切正常。
我不是 IPython 的用户,所以我不能确切地说出发生了什么,但我猜这是在你的 __init__.py
中使用 from file2 import *
的症状文件。
当您使用 package.Derived
创建 Derived
class 的实例时,您不会获得 class 的最新版本,但是首次加载包时的旧版本,from file2 import *
语句为 运行。当您修改模块代码并 IPython 重新加载它时,会更改 package.file2.Derived
,但不会 package.Derived
.
但是,旧版本的 class 仍然引用其模块的名称空间,并且当它尝试在 super
调用中按名称查找自身时,它找到了较新的版本的 class 代替。这就是为什么会出现错误,因为两个 Derived
class 不一样。
如果您直接访问 package.file2.Derived
,您可能会避免这个问题。这将始终让您进入 class 的当前版本,super
调用应该不会有任何问题。请注意,如果在您修改模块之前仍然存在 class 的实例,您可能仍然会遇到问题(但这可能并不奇怪)。
在 Python 3 中,使用新的 super().__init__()
而不是 super(Derived, self).__init__()
解决了我的问题
我有 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 控制台之前,这不会消失。为什么 autoreload 不能正确处理这个问题?如果我将 Base 和 Derived 放入单个模块文件而不是包中,一切正常。
我不是 IPython 的用户,所以我不能确切地说出发生了什么,但我猜这是在你的 __init__.py
中使用 from file2 import *
的症状文件。
当您使用 package.Derived
创建 Derived
class 的实例时,您不会获得 class 的最新版本,但是首次加载包时的旧版本,from file2 import *
语句为 运行。当您修改模块代码并 IPython 重新加载它时,会更改 package.file2.Derived
,但不会 package.Derived
.
但是,旧版本的 class 仍然引用其模块的名称空间,并且当它尝试在 super
调用中按名称查找自身时,它找到了较新的版本的 class 代替。这就是为什么会出现错误,因为两个 Derived
class 不一样。
如果您直接访问 package.file2.Derived
,您可能会避免这个问题。这将始终让您进入 class 的当前版本,super
调用应该不会有任何问题。请注意,如果在您修改模块之前仍然存在 class 的实例,您可能仍然会遇到问题(但这可能并不奇怪)。
在 Python 3 中,使用新的 super().__init__()
而不是 super(Derived, self).__init__()
解决了我的问题