当前位置: 首页 > 面试题库 >

用pyximport重新加载模块?

仉俊能
2023-03-14
问题内容

我有一个python程序,在运行之前会加载很多数据。因此,我希望能够在不重新加载数据的情况下重新加载代码。与常规python一起,importlib.reload运行良好。这是一个例子:

setup.py:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize

extensions = [
    Extension("foo.bar", ["foo/bar.pyx"],
              language="c++",
              extra_compile_args=["-std=c++11"],
              extra_link_args=["-std=c++11"])
]
setup(
    name="system2",
    ext_modules=cythonize(extensions, compiler_directives={'language_level' : "3"}),
)

foo / bar.py

cpdef say_hello():
    print('Hello!')

Runner.py:

import pyximport
pyximport.install(reload_support=True)

import foo.bar
import subprocess
from importlib import reload

if __name__ == '__main__':

    def reload_bar():
        p = subprocess.Popen('python setup.py build_ext --inplace',
                             shell=True,
                             cwd='<your directory>')
        p.wait()

        reload(foo.bar)
        foo.bar.say_hello()

但这似乎不起作用。如果我编辑bar.pyx并运行reload_bar,则看不到我的更改。我也pyximport.build_module()没有运气尝试过-
重建了模块但没有重新加载。我在“普通” python外壳中运行,如果有区别,则不是IPython。


问题答案:

与Python 3.x相比,我能够获得一个适用于Python
2.xa的解决方案。无论出于何种原因,Cython似乎都在缓存.so从中导入模块的可共享对象()文件,即使在运行时重建并删除了旧文件之后,它仍会从旧的可共享对象文件中导入。但是,无论如何这都是没有必要的(当您import foo.bar创建时,它不会创建一个),因此我们还是可以跳过这一步。

最大的问题是,即使在reloading之后,python仍保留对旧模块的引用。普通的python模块似乎可以找到,但是与cython无关。为了解决这个问题,我运行了两个语句来代替reload(foo.bar)

del sys.modules['foo.bar']
import foo.bar

这样可以成功(尽管可能效率较低)重新加载cython模块。运行该子流程的Python
3.x中唯一存在的问题是创建有问题的可共享对象。取而代之的是一起跳过所有内容,让它import foo.barpyximporter模块一起发挥作用,然后为您重新编译。我还向pyxinstall命令添加了一个选项,以指定语言级别以匹配您在setup.py

pyximport.install(reload_support=True, language_level=3)

所以一起:

运行器

import sys
import pyximport
pyximport.install(reload_support=True, language_level=3)

import foo.bar

if __name__ == '__main__':
    def reload_bar():
        del sys.modules['foo.bar']
        import foo.bar

    foo.bar.say_hello()
    input("  press enter to proceed  ")
    reload_bar()
    foo.bar.say_hello()

其他两个文件保持不变

运行:

Hello!
  press enter to proceed

-replace"Hello!"富/ bar.pyx"Hello world!",并按Enter

Hello world!


 类似资料:
  • 我有一个python程序,它在运行之前加载了大量数据。因此,我希望能够在不重新加载数据的情况下重新加载代码。对于常规python, reload\u bar我看不到我的更改。我还尝试了pyximport。build\u module()运气不好--模块已重建,但没有重新加载。我在一个“普通”的python shell中运行,如果有什么不同的话,就不是IPython。

  • 问题 你想重新加载已经加载的模块,因为你对其源码进行了修改。 解决方案 使用imp.reload()来重新加载先前加载的模块。举个例子: >>> import spam >>> import imp >>> imp.reload(spam) <module 'spam' from './spam.py'> >>> 讨论 重新加载模块在开发和调试过程中常常很有用。但在生产环境中的代码使用会不安全,因

  • 问题内容: 我有一台运行时间较长的Python服务器,并且希望能够在不重新启动服务器的情况下升级服务。最好的方法是什么? 问题答案: 你可以使用reload内置函数重新加载已导入的模块: 在Python 3中,已移至imp模块。在3.4中,不推荐使用importlib,而在中添加了。当定位到3或更高版本时,在调用reload或导入时参考相应的模块。 我认为这就是你想要的。诸如Django开发服务器

  • 问题内容: 我有一个运行时间较长的Python服务器,并且希望能够在不重新启动服务器的情况下升级服务。最好的方法是什么? 问题答案: 您可以使用reload内置函数(仅适用于Python 3.4+)重新导入已导入的模块: 在Python 3中,已移至模块。在3.4中,imp不推荐使用,而reload在中添加了。当定位到3或更高版本时,在调用reload或导入时参考相应的模块。 我认为这就是您想要的

  • 问题内容: 当用户访问未经授权的个人页面(例如个人资料)时,我的后端302重定向到控制器操作,该操作代替部分个人资料来提供登录部分。由于它302重定向到返回部分操作的动作,因此URL地址栏与用户尝试访问的页面(“ / profile”)没有变化。 我本来打算“修复”该问题,但实际上我认为它可以提供良好的用户体验,而不是将返回网址作为查询参数来处理。 想法是一旦他们登录,我只想重新加载当前路由,也可

  • 问题内容: 目前,我正在处理一个包含子模块并使用numpy / scipy的python项目。Ipython用作交互式控制台。不幸的是,我对现在使用的工作流程不是很满意,请多多指教。 在IPython中,该框架是通过一个简单的命令加载的。但是,通常有必要在框架的子模块之一中更改代码。至此,一个模型已经加载完毕,我使用IPython与之交互。 现在,该框架包含许多相互依赖的模块,即,在最初加载框架时

  • 问题内容: 我在页面上有两个iframe,一个对另一个iframe进行了更改,但是另一个iframe直到刷新后才显示更改。有没有一种简单的方法可以使用jQuery刷新此iframe? 问题答案: 如果iframe不在其他域中,则可以执行以下操作: 但是,由于iframe位于其他域中,因此同源策略将拒绝您访问iframe的属性。 但是,如果您的代码在iframe的父页面上运行,则可以通过将其src属

  • 问题内容: 有没有办法让IPython自动重新加载所有更改的代码?在外壳中执行每行之前,或者在明确要求时失败。我正在使用IPython和SciPy进行很多探索性编程,每当更改模块时都必须手动重新加载每个模块,这是很痛苦的。 问题答案: 对于IPython版本3.1、4.x和5.x 然后,您的模块将默认 自动重新加载 。这是文档: 有一个窍门:当您使用时 忘记 以上 所有 内容时,请尝试: