从控制台重新加载python模块的正确方法

时间:2021-03-15 13:13:22

I'm debugging from the python console and would like to reload a module every time I make a change so I don't have to exit the console and re-enter it. I'm doing:

我正在从python控制台调试,并希望每次进行更改时重新加载模块,所以我不必退出控制台并重新输入它。我正在做:

>>> from project.model.user import *
>>> reload(user)

but I receive:

但我收到:

>>>NameError: name 'user' is not defined

What is the proper way to reload the entire user class? Is there a better way to do this, perhaps auto-updating while debugging?

重新加载整个用户类的正确方法是什么?有没有更好的方法来做到这一点,也许在调试时自动更新?

Thanks.

6 个解决方案

#1


34  

As asked, the best you can do is

如所问,你能做的最好的是

>>> from project.models.user import *
>>> import project # get module reference for reload
>>> reload(project.models.user) # reload step 1
>>> from project.models.user import * # reload step 2

it would be better and cleaner if you used the user module directly, rather than doing import * (which is almost never the right way to do it). Then it would just be

如果直接使用用户模块,而不是进行导入*(这几乎不是正确的方法),它会更好更清洁。那就是

>>> from project.models import user
>>> reload(user)

This would do what you want. But, it's not very nice. If you really need to reload modules so often, I've got to ask: why?

这可以做你想要的。但是,它不是很好。如果你真的需要经常重新加载模块,我必须问:为什么?

My suspicion (backed up by previous experience with people asking similar questions) is that you're testing your module. There are lots of ways to test a module out, and doing it by hand in the interactive interpreter is among the worst ways. Save one of your sessions to a file and use doctest, for a quick fix. Alternatively, write it out as a program and use python -i. The only really great solution, though, is using the unittest module.

我怀疑(以前人们提出类似问题的经验支持)是你正在测试你的模块。有很多方法可以测试模块,在交互式解释器中手动执行是最糟糕的方法。将您的一个会话保存到文件并使用doctest进行快速修复。或者,将其作为程序写出来并使用python -i。但是,唯一真正优秀的解决方案是使用unittest模块。

If that's not it, hopefully it's something better, not worse. There's really no good use of reload (in fact, it's removed in 3.x). It doesn't work effectively-- you might reload a module but leave leftovers from previous versions. It doesn't even work on all kinds of modules-- extension modules will not reload properly, or sometimes even break horribly, when reloaded.

如果那不是它,希望它更好,而不是更糟。实际上并没有很好地利用重载(事实上,它已经在3.x中删除了)。它无法有效工作 - 您可能会重新加载模块,但会留下以前版本的剩余部分。它甚至不适用于所有类型的模块 - 扩展模块在重新加载时不会正确地重新加载,或者有时甚至会破坏。

The context of using it in the interactive interpreter doesn't leave a lot of choices as to what you are doing, and what the real best solution would be. Outside it, sometimes people used reload() to implement plugins etc. This is dangerous at best, and can frequently be done differently using either exec (ah the evil territory we find ourselves in), or a segregated process.

在交互式解释器中使用它的上下文并没有为你正在做什么做出很多选择,以及真正最好的解决方案是什么。在它之外,有时候人们使用reload()来实现插件等。这最好是危险的,并且经常可以使用exec(我们发现自己的邪恶领域啊)或隔离过程来做不同的事情。

#2


4  

You can't use reload() in a effective way.

您不能以有效的方式使用reload()。

Python does not provide an effective support for reloading or unloading of previously imported modules; module references makes it impractical to reload a module because references could exist in many places of your program.

Python不能为重载或卸载以前导入的模块提供有效的支持;模块引用使得重新加载模块变得不切实际,因为引用可能存在于程序的许多地方。

Python 3 has removed reload() feature entirely.

Python 3完全删除了reload()功能。

#3


4  

Unfortunately you've got to use:

不幸的是你必须使用:

>>> from project.model import user
>>> reload(user)

I don't know off the top of my head of something which will automatically reload modules at the interactive prompt… But I don't see any reason one shouldn't exist (in fact, it wouldn't be too hard to implement, either…)

我不知道在交互式提示下会自动重新加载模块的东西......但我没有看到任何不应存在的理由(事实上,它实现起来并不难,要么...)

Now, you could do something like this:

现在,你可以这样做:

from types import ModuleType
import sys
_reload_builtin = reload
def reload(thing):
    if isinstance(thing, ModuleType):
        _reload_builtin(thing)
    elif hasattr(thing, '__module__') and thing.__module__:
        module = sys.modules[thing.__module__]
        _reload_builtin(module)
    else:
        raise TypeError, "reload() argument must be a module or have an __module__"

#4


1  

IPython can reload modules before executing every new line:

IPython可以在执行每个新行之前重新加载模块:

%load_ext autoreload
%autoreload 2

Where %autoreload 2reloads "all modules (except those excluded by %aimport) every time before executing the Python code typed."

每次执行输入的Python代码之前%%autoreload 2都会加载“所有模块(%aimport排除的模块除外)”。

See the docs:

查看文档:

#5


1  

For python3, reload has been moved to imp module. you can use imp.reload(). You can refer to this post.

对于python3,重载已移至imp模块。你可以使用imp.reload()。你可以参考这篇文章。

>>> import imp
>>> import project # get module reference for reload
>>> imp.reload(project.models.user) # reload step 1
>>> from project.models.user import * # reload step 2

#6


0  

You could also try twisted.python.rebuild.rebuild.

您也可以尝试twisted.python.rebuild.rebuild。

#1


34  

As asked, the best you can do is

如所问,你能做的最好的是

>>> from project.models.user import *
>>> import project # get module reference for reload
>>> reload(project.models.user) # reload step 1
>>> from project.models.user import * # reload step 2

it would be better and cleaner if you used the user module directly, rather than doing import * (which is almost never the right way to do it). Then it would just be

如果直接使用用户模块,而不是进行导入*(这几乎不是正确的方法),它会更好更清洁。那就是

>>> from project.models import user
>>> reload(user)

This would do what you want. But, it's not very nice. If you really need to reload modules so often, I've got to ask: why?

这可以做你想要的。但是,它不是很好。如果你真的需要经常重新加载模块,我必须问:为什么?

My suspicion (backed up by previous experience with people asking similar questions) is that you're testing your module. There are lots of ways to test a module out, and doing it by hand in the interactive interpreter is among the worst ways. Save one of your sessions to a file and use doctest, for a quick fix. Alternatively, write it out as a program and use python -i. The only really great solution, though, is using the unittest module.

我怀疑(以前人们提出类似问题的经验支持)是你正在测试你的模块。有很多方法可以测试模块,在交互式解释器中手动执行是最糟糕的方法。将您的一个会话保存到文件并使用doctest进行快速修复。或者,将其作为程序写出来并使用python -i。但是,唯一真正优秀的解决方案是使用unittest模块。

If that's not it, hopefully it's something better, not worse. There's really no good use of reload (in fact, it's removed in 3.x). It doesn't work effectively-- you might reload a module but leave leftovers from previous versions. It doesn't even work on all kinds of modules-- extension modules will not reload properly, or sometimes even break horribly, when reloaded.

如果那不是它,希望它更好,而不是更糟。实际上并没有很好地利用重载(事实上,它已经在3.x中删除了)。它无法有效工作 - 您可能会重新加载模块,但会留下以前版本的剩余部分。它甚至不适用于所有类型的模块 - 扩展模块在重新加载时不会正确地重新加载,或者有时甚至会破坏。

The context of using it in the interactive interpreter doesn't leave a lot of choices as to what you are doing, and what the real best solution would be. Outside it, sometimes people used reload() to implement plugins etc. This is dangerous at best, and can frequently be done differently using either exec (ah the evil territory we find ourselves in), or a segregated process.

在交互式解释器中使用它的上下文并没有为你正在做什么做出很多选择,以及真正最好的解决方案是什么。在它之外,有时候人们使用reload()来实现插件等。这最好是危险的,并且经常可以使用exec(我们发现自己的邪恶领域啊)或隔离过程来做不同的事情。

#2


4  

You can't use reload() in a effective way.

您不能以有效的方式使用reload()。

Python does not provide an effective support for reloading or unloading of previously imported modules; module references makes it impractical to reload a module because references could exist in many places of your program.

Python不能为重载或卸载以前导入的模块提供有效的支持;模块引用使得重新加载模块变得不切实际,因为引用可能存在于程序的许多地方。

Python 3 has removed reload() feature entirely.

Python 3完全删除了reload()功能。

#3


4  

Unfortunately you've got to use:

不幸的是你必须使用:

>>> from project.model import user
>>> reload(user)

I don't know off the top of my head of something which will automatically reload modules at the interactive prompt… But I don't see any reason one shouldn't exist (in fact, it wouldn't be too hard to implement, either…)

我不知道在交互式提示下会自动重新加载模块的东西......但我没有看到任何不应存在的理由(事实上,它实现起来并不难,要么...)

Now, you could do something like this:

现在,你可以这样做:

from types import ModuleType
import sys
_reload_builtin = reload
def reload(thing):
    if isinstance(thing, ModuleType):
        _reload_builtin(thing)
    elif hasattr(thing, '__module__') and thing.__module__:
        module = sys.modules[thing.__module__]
        _reload_builtin(module)
    else:
        raise TypeError, "reload() argument must be a module or have an __module__"

#4


1  

IPython can reload modules before executing every new line:

IPython可以在执行每个新行之前重新加载模块:

%load_ext autoreload
%autoreload 2

Where %autoreload 2reloads "all modules (except those excluded by %aimport) every time before executing the Python code typed."

每次执行输入的Python代码之前%%autoreload 2都会加载“所有模块(%aimport排除的模块除外)”。

See the docs:

查看文档:

#5


1  

For python3, reload has been moved to imp module. you can use imp.reload(). You can refer to this post.

对于python3,重载已移至imp模块。你可以使用imp.reload()。你可以参考这篇文章。

>>> import imp
>>> import project # get module reference for reload
>>> imp.reload(project.models.user) # reload step 1
>>> from project.models.user import * # reload step 2

#6


0  

You could also try twisted.python.rebuild.rebuild.

您也可以尝试twisted.python.rebuild.rebuild。