有没有什么方法可以在不关闭 JMP 会话的情况下清除 JMP Python 端的“所有内容”(类似于 JSL 中的 Delete Symbols() 或重新启动内核的方法)?
我正在与同事一起利用 JMP Python 集成开发应用程序,当我们对 Python 代码进行更改时,我们必须不断关闭 JMP。我们这样做是为了“清除”Python,因为我们遇到旧 Python 代码在内存中且导入不会覆盖已导入代码的问题。
更新了被忽略的模块。许多惊喜和奇迹 - 直到你注意到...
啊!
del有用吗?
import sys
print(sys.path)
del sys
print(sys.path)
存在问题。在大多数 Python 脚本中,这个问题不太明显,因为 Python 本身的生命周期通常与脚本相同。如果您在较长的会话中以交互方式运行 Python,并在同一个交互式会话中执行多项操作,您就会开始注意到这一点。这进一步复杂化了某些 Python 包是用 C/C++(甚至 Fortran)实现的,例如 NumPy。Python 将它们加载为共享库,除了重新启动之外,没有安全的方法可以从正在运行的进程中卸载共享库。JMP 与 Python 共享库本身处于类似的位置,它无法卸载。是的, del可以释放对象。但是,del sys 并没有做您期望的事情。这不是删除或卸载“模块”或卸载依赖的 dll,它只是删除保存对已加载模块的引用的“sys”对象。另一方面是 sys 是 Python 内置模块,与加载的模块不同。进一步删除“sys”不会清除您可能所做的任何更改,例如将另一条路径附加到 sys.path。
如果你这样做:
sys.path.append('/usr/local/bin')
print(sys.path)
del sys
print(sys.path). # gives error on sys
import sys
print(sys.path). # still contains the /usr/local/bin addition
以上内容是在终端窗口的交互式会话中运行的。只有退出 Python 并重新启动才能从 sys.path 中清除 /usr/local/bin。唯一真正的方法是跟踪会话中使用的所有变量,然后在“会话”结束时删除它们。一种方法是将每个变量放入列表或字典中,然后在会话结束时删除容器。
我正在研究使用 Python 子解释器,它可以允许设置不在全局环境中运行的代码,其想法是子解释器是独立的,关闭子解释器就像关闭并重新启动 Python 一样。目前,我还没有找到在 JMP 会话的生命周期内安全关闭和重新启动主 Python 解释器的方法。
目前 Python 重新加载模块的做法(从 Python 3.4 开始)是
<SPAN class="hljs-keyword">import</SPAN> importlib
importlib.reload(modulename)
尝试重新加载系统
>>> importlib.reload(sys)
重新加载 numpy,给出以下输出...
>>> importlib.reload(np)
/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/importlib/__init__.py:169: UserWarning: The NumPy module was reloaded (imported a second time). This can in some cases result in small but subtle issues and is discouraged.
_bootstrap._exec(spec, module)
请注意用户警告:
用户警告:NumPy 模块已重新加载(第二次导入)。在某些情况下,这可能会导致一些细微的问题,因此不建议这样做。_bootstrap._exec(spec, module)
即使采用“官方”方式重新加载模块也可能会导致问题。
importlib.reload() 非常适合在代码中开发 Python 模块,因为模块源代码的更改只有在重新加载时才会反映出来。这可能会强制重新编译 Python 代码为 .pyc。