我有python代码跨越几个文件,为了方便我打包,最后在my_package目录下有以下3个文件:
__init__.py
Run Code Online (Sandbox Code Playgroud)
内容:
from file1 import *
from file2 import *
Run Code Online (Sandbox Code Playgroud)
file1.py内容:
class Base(object):
pass
Run Code Online (Sandbox Code Playgroud)
file2.py内容:
from file1 import Base
class Derived(Base):
def __init__(self):
return super(Derived, self).__init__()
Run Code Online (Sandbox Code Playgroud)
然后我在IPython中执行:
>>>%autoreload 2
>>>import my_package
>>>t = my_package.Derived()
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但后来我对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
Run Code Online (Sandbox Code Playgroud)
在我重新启动IPython控制台之前,这不会消失.为什么不自动重载正确处理?如果我将Base和Derived放入单个模块文件而不是包中,一切都有效.
Blc*_*ght 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调用有任何问题.请注意,如果在修改模块之前仍然存在该类的实例,则可能仍然存在问题(但这可能并不令人惊讶).
| 归档时间: |
|
| 查看次数: |
4140 次 |
| 最近记录: |