如何在python shell中重新加载一个类?

时间:2011-08-04 18:08:11

标签: python ipython

如果我导入定义属于某个包的同名类的模块,则由于父包的__init__.py而将其导入为Class而不是Module。有关详细信息,请参阅different import results at different directories。在Python shell或ipython shell中,如果我这样做

from MyPak import MyMod

MyModule总是作为Class导入,因此我无法重新加载它(reload()仅适用于模块)。运行

from MyPak import MyMod

似乎没有更新类定义。任何人都可以建议一种方法来更新python shell中的类?

PS。无需重新启动python解释器。

PPS 即可。万一你手头有代码并想测试它:我实际上是在谈论BioPython,我正在研究Bio.PDB.PDBParser。我有一个ipython shell(v0.10)并编辑PDBParser.py。无法在ipython中重新加载它。

所以这就是我所做的:

# start ipython v0.10
import Bio
from Bio.PDB import PDBParser
p = PDBParser()
s = p.get_structure()
# then I make changes,e.g. simply print some text, in PDBParser.py
del Bio
del PDBParser
del s
import Bio  # or reload(Bio) without deleting all the objects
from Bio.PDB import PDBParser
p = PDBParser()
s = p.get_structure() # expected output after change not seen :(

我看不到打印的文字。这些变化没有以某种方式应用。

6 个答案:

答案 0 :(得分:59)

仅在Python 3上,导入reload函数:

>>> from importlib import reload

在Python 2.x和3.x上,您只需在模块上调用reload

>>> import MyPak
>>> reload(MyPak)
>>> from MyPak import MyMod

但是,旧类的实例不会更新(根本没有描述更新机制的代码)。

答案 1 :(得分:34)

我终于找到了答案:

import MyPak
from MyPak import MyMod

编辑MyPak/MyMod.py文件后,要重新加载文件MyMod中的课程MyMod.py,需要

import sys
del sys.modules['MyPak.MyMod'] 
reload(MyPak)
from MyPak import MyMod

<强>注意事项

  1. 执行del MyPakdel MyModdel MyPak.MyMod并不能解决问题,因为它只是删除了名称绑定。 Python仅搜索sys.modules以查看模块是否已导入。查看帖子module name in sys.modules and globals()中的讨论。

  2. 重新加载MyPak时,python尝试执行from MyMod import MyMod中的行MyPak/__init__.py。但是,它会在MyPak.MyMod中找到sys.modules,因此它会 尽管MyMod已更新,但重新加载MyPak/MyMod.py。而且您会发现没有生成新的MyPak/MyMod.pyc

答案 2 :(得分:9)

有办法解决这个问题:

1。使用import MyPak.MyMod代替from MyPak import MyMod

然后你可以写:

from importlib import reload  # If on Python 3
import MyPak.MyMod
reload(MyPak.MyMod)

它有效。

2。使用Constants to test AX against after fnstsw for various conditions

from MyPak import MyMod
from IPython.lib.deepreload import reload
reload(MyPak)  # This should also reload all submodules

3。使用IPython.lib.deepreload魔法

%load_ext autoreload
%autoreload 2
import MyPak.MyMod  # All changes to MyPak.MyMod will be loaded automatically

答案 3 :(得分:5)

我有一个myfile.py文件,其中包含一个类MyClass

要导入,只需执行:

from myfile import MyClass
mc = MyClass()

重新加载:

import sys
del sys.modules['myfile']
from myfile import MyClass
modifiedmc = MyClass()

这在构建模块时非常有用。 一个人可以把这些放在一个函数中,然后调用函数

def myreload():
   import sys
   del sys.modules['myfile']
   from myfile import MyClass
   modifiedmc = MyClass()
   global mc
   mc = modifiedmc

答案 4 :(得分:4)

您可以使用魔术功能:

%load_ext autoreload
%autoreload 2
from MyPak import MyMod

答案 5 :(得分:0)

它适用于我使用python 3.5.2:

import importlib
importlib.reload(class)
from class import module