Python 如何在 django shell 中重新加载模块?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3772260/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to reload modules in django shell?
提问by Mad Wombat
I am working with Django and use Django shell all the time. The annoying part is that while the Django server reloads on code changes, the shell does not, so every time I make a change to a method I am testing, I need to quit the shell and restart it, re-import all the modules I need, reinitialize all the variables I need etc. While iPython history saves a lot of typing on this, this is still a pain. Is there a way to make django shell auto-reload, the same way django development server does?
我正在使用 Django 并一直使用 Django shell。烦人的部分是,虽然 Django 服务器在代码更改时重新加载,但 shell 不会,所以每次我对我正在测试的方法进行更改时,我都需要退出 shell 并重新启动它,重新导入我的所有模块需要,重新初始化我需要的所有变量等。虽然 iPython 历史记录在此方面节省了大量输入,但这仍然很痛苦。有没有办法让 django shell 自动重新加载,就像 django 开发服务器一样?
I know about reload(), but I import a lot of models and generally use from app.models import *syntax, so reload() is not much help.
我知道reload(),但是我导入了很多模型并且一般都使用from app.models import *语法,所以reload() 帮助不大。
采纳答案by mpaf
I recommend using the django-extensions project like stated above by dongweiming. But instead of just 'shell_plus' management command, use:
我建议使用 dongweiming 上面提到的 django-extensions 项目。但不仅仅是“shell_plus”管理命令,请使用:
manage.py shell_plus --notebook
This will open a IPython notebook on your web browser. Write your code there in a cell, your imports etc. and run it.
这将在您的网络浏览器上打开一个 IPython 笔记本。在单元格、导入等中编写代码并运行它。
When you change your modules, just click the notebook menu item 'Kernel->Restart'
更改模块时,只需单击笔记本菜单项“内核->重启”
There you go, your code is now using your modified modules.
好了,您的代码现在正在使用修改后的模块。
回答by Tomasz Zieliński
Reload() doesn't work in Django shell without some tricks. You can check this thread na and my answer specifically:
Reload() 在没有一些技巧的情况下在 Django shell 中不起作用。您可以具体检查此线程 na 和我的答案:
How do you reload a Django model module using the interactive interpreter via "manage.py shell"?
回答by Mad Wombat
It seems that the general consensus on this topic, is that python reload() sucks and there is no good way to do this.
似乎关于这个话题的普遍共识是,python reload() 很糟糕,没有好的方法可以做到这一点。
回答by dongweiming
look at the manage.py shell_plus command provided by the django-extensionsproject. It will load all your model files on shell startup. and autoreload your any modify but do not need exit, you can direct call there
查看django-extensions项目提供的manage.py shell_plus命令。它将在 shell 启动时加载所有模型文件。并自动重新加载您的任何修改但不需要退出,您可以直接调用那里
回答by thomaspaulb
回答by toabi
Not exactly what you want, but I now tend to build myself management commands for testing and fiddling with things.
不完全是你想要的,但我现在倾向于为自己建立管理命令来测试和摆弄东西。
In the command you can set up a bunch of locals the way you want and afterwards drop into an interactive shell.
在命令中,您可以按照自己的方式设置一堆本地人,然后放入交互式 shell。
import code
class Command(BaseCommand):
def handle(self, *args, **kwargs):
foo = 'bar'
code.interact(local=locals())
No reload, but an easy and less annoying way to interactively test django functionality.
无需重新加载,而是一种以交互方式测试 django 功能的简单且不那么烦人的方式。
回答by Erik
My solution to it is I write the code and save to a file and then use:
我的解决方案是我编写代码并保存到文件中,然后使用:
python manage.py shell < test.py
python manage.py shell < test.py
So I can make the change, save and run that command again till I fix whatever I'm trying to fix.
所以我可以进行更改,保存并再次运行该命令,直到我修复了我想要修复的任何内容。
回答by Roque
My solution for this inconvenient follows. I am using IPython.
我对这种不便的解决方案如下。我正在使用 IPython。
$ ./manage.py shell
> import myapp.models as mdls # 'mdls' or whatever you want, but short...
> mdls.SomeModel.objects.get(pk=100)
> # At this point save some changes in the model
> reload(mdls)
> mdls.SomeModel.objects.get(pk=100)
For Python 3.x, 'reload' must be imported using:
对于Python 3.x,必须使用以下命令导入“reload”:
from importlib import reload
Hope it helps. Of course it is for debug purposes.
希望能帮助到你。当然,这是为了调试目的。
Cheers.
干杯。
回答by bodolsog
I'd suggest use IPython autoreload extension.
我建议使用 IPython autoreload extension。
./manage.py shell
In [1]: %load_ext autoreload
In [2]: %autoreload 2
And from now all imported modules would be refreshed before evaluate.
从现在开始,所有导入的模块都将在评估之前刷新。
In [3]: from x import print_something
In [4]: print_something()
Out[4]: 'Something'
# Do changes in print_something method in x.py file.
In [5]: print_something()
Out[5]: 'Something else'
Works also if something was imported before %load_ext autoreloadcommand.
如果在%load_ext autoreload命令之前导入了某些内容,也可以使用。
./manage.py shell
In [1]: from x import print_something
In [2]: print_something()
Out[2]: 'Something'
# Do changes in print_something method in x.py file.
In [3]: %load_ext autoreload
In [4]: %autoreload 2
In [5]: print_something()
Out[5]: 'Something else'
There is possible also prevent some imports from refreshing with %aimportcommand and 3 autoreload strategies:
还可以使用%aimport命令和 3 种自动重新加载策略来防止某些导入刷新:
%autoreload
- Reload all modules (except those excluded by %aimport) automatically now.
%autoreload 0
- Disable automatic reloading.
%autoreload 1
- Reload all modules imported with %aimport every time before executing the Python code typed.
%autoreload 2
- Reload all modules (except those excluded by %aimport) every time before executing the Python code typed.
%aimport
- List modules which are to be automatically imported or not to be imported.
%aimport foo
- Import module ‘foo' and mark it to be autoreloaded for %autoreload 1
%aimport -foo
- Mark module ‘foo' to not be autoreloaded.
%自动重载
- 现在自动重新加载所有模块(除了那些被 %aimport 排除的模块)。
%自动重载 0
- 禁用自动重新加载。
%自动重载 1
- 在执行输入的 Python 代码之前,每次都重新加载使用 %aimport 导入的所有模块。
%自动重载 2
- 每次在执行输入的 Python 代码之前重新加载所有模块(除了那些被 %aimport 排除的模块)。
%aimport
- 列出要自动导入或不导入的模块。
%aimport foo
- 导入模块 'foo' 并将其标记为为 %autoreload 1 自动重新加载
%aimport -foo
- 将模块 'foo' 标记为不自动重新加载。
This generally works good for my use, but there are some cavetas:
这通常对我有用,但有一些警告:
- Replacing code objects does not always succeed: changing a @property in a class to an ordinary method or a method to a member variable can cause problems (but in old objects only).
- Functions that are removed (eg. via monkey-patching) from a module before it is reloaded are not upgraded.
- C extension modules cannot be reloaded, and so cannot be autoreloaded.
- 替换代码对象并不总是成功:将类中的@property 更改为普通方法或将方法更改为成员变量可能会导致问题(但仅限于旧对象)。
- 在重新加载之前从模块中删除(例如通过猴子补丁)的功能不会升级。
- C 扩展模块无法重新加载,因此无法自动重新加载。
回答by andorov
Use shell_pluswith an ipython config. This will enable autoreloadbefore shell_plus automatically imports anything.
将shell_plus与 ipython 配置一起使用。这将autoreload在 shell_plus 自动导入任何内容之前启用。
pip install django-extensions
pip install ipython
ipython profile create
Edit your ipython profile (~/.ipython/profile_default/ipython_config.py):
编辑您的 ipython 配置文件 ( ~/.ipython/profile_default/ipython_config.py):
c.InteractiveShellApp.exec_lines = ['%autoreload 2']
c.InteractiveShellApp.extensions = ['autoreload']
Open a shell - note that you do not need to include --ipython:
打开一个 shell - 请注意,您不需要包括--ipython:
python manage.py shell_plus
Now anything defined in SHELL_PLUS_PRE_IMPORTSor SHELL_PLUS_POST_IMPORTS(docs) will autoreload!
现在任何在SHELL_PLUS_PRE_IMPORTSor SHELL_PLUS_POST_IMPORTS( docs) 中定义的东西都会自动重新加载!
Note that if your shell is at a debugger (ex pdb.set_trace()) when you save a file it can interfere with the reload.
请注意,如果您的 shell 在pdb.set_trace()您保存文件时处于调试器(ex )中,它可能会干扰重新加载。

