自动重新加载和导致TypeError的包:super(type,obj):obj必须是类型的实例或子类型 [英] autoreload and package causing TypeError: super(type, obj): obj must be an instance or subtype of type

查看:894
本文介绍了自动重新加载和导致TypeError的包:super(type,obj):obj必须是类型的实例或子类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了方便起见,我有python代码跨越了几个文件,这些文件以my_package目录下的以下3个文件结尾:

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

内容:

from file1 import *
from file2 import *

file1.py内容:

file1.py contents:

class Base(object):
    pass

file2.py内容:

file2.py contents:

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

然后我在IPython中执行:

I then execute in IPython:

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

到目前为止,一切都很好. 但是随后我对file2.py进行了更改,比如说添加了一个哑属性. 现在,当我执行时:

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

直到我重新启动IPython控制台,这种情况才会消失.为什么自动重装不能正确处理此问题?如果将Base和Derived放到一个模块文件而不是包中,一切都会正常工作.

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.

推荐答案

我不是IPython的用户,所以我不能确切说出发生了什么,但是我想这是在中使用from file2 import *的症状您的__init__.py文件.

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.

使用package.Derived创建Derived类的实例时,您没有获得该类的最新版本,而是获得了首次加载该软件包时最新的旧版本以及from file2 import *语句已运行.当您修改模块代码并IPython重新加载它时,这更改了package.file2.Derived,但没有更改package.Derived.

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.

但是,该类的旧版本仍然引用其模块的命名空间,并且当它尝试在super调用中按名称查找自身时,它将查找该类的较新版本.这就是为什么会出现错误的原因,因为两个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.

如果直接访问package.file2.Derived,则可能会避免此问题.这将始终使您进入该类的当前版本,该版本在super调用中应该没有任何问题.请注意,如果仍然有在修改模块之前创建的类的实例,则可能仍然有问题(但这可能并不十分令人惊讶).

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).

这篇关于自动重新加载和导致TypeError的包:super(type,obj):obj必须是类型的实例或子类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆