我有一个长期运行的Python服务器,希望能够在不重新启动服务器的情况下升级服务。最好的方法是什么?

if foo.py has changed:
    unimport foo  <-- How do I do this?
    import foo
    myfoo = foo.Foo()

当前回答

如果一个模块不是纯Python的,那么删除它会特别困难。

下面是来自:如何真正删除导入的模块?

您可以使用sys.getrefcount()来找出的实际数量 参考文献

>>> import sys, empty, os
>>> sys.getrefcount(sys)
9
>>> sys.getrefcount(os)
6
>>> sys.getrefcount(empty)
3

大于3的数字表示 它将很难摆脱 模块。本土的“空” (不包含任何内容)模块应该 垃圾收集后

>>> del sys.modules["empty"]
>>> del empty

因为第三个参考是一个人工制品 getrefcount()函数的。

其他回答

对于Python 2,使用内置函数reload:

reload(module)

对于Python 2和Python 3.2-3.3,使用reload from module imp:

import imp
imp.reload(module)

对于Python≥3.4,imp已弃用,改用importlib,因此使用以下命令:

import importlib
importlib.reload(module)

or:

from importlib import reload
reload(module)

TL; diana:

Python≥3.4:importlib.reload(module) Python 3.2 - 3.3: imp.reload(module) Python 2: reload(module)

以Abaqus为例,这就是它的工作方式。 假设你的文件是Class_VerticesEdges.py

sys.path.append('D:\...\My Pythons')
if 'Class_VerticesEdges' in sys.modules:  
    del sys.modules['Class_VerticesEdges']
    print 'old module Class_VerticesEdges deleted'
from Class_VerticesEdges import *
reload(sys.modules['Class_VerticesEdges'])
if 'myModule' in sys.modules:  
    del sys.modules["myModule"]

接受的答案不处理from X import Y的情况。这段代码处理了它和标准的导入情况:

def importOrReload(module_name, *names):
    import sys

    if module_name in sys.modules:
        reload(sys.modules[module_name])
    else:
        __import__(module_name, fromlist=names)

    for name in names:
        globals()[name] = getattr(sys.modules[module_name], name)

# use instead of: from dfly_parser import parseMessages
importOrReload("dfly_parser", "parseMessages")

在重新加载的情况下,我们将顶级名称重新分配给新加载的模块中存储的值,从而更新这些值。

如果你遇到以下错误,这个答案可能会帮助你得到一个解决方案:

回溯(最近一次调用): 文件“FFFF”,第1行 NameError: name 'YYYY'没有定义

OR

回溯(最近一次调用): 文件“FFFF”,第1行 文件"/usr/local/lib/python3.7/importlib/__init__.py",第140行,重新加载 抛出TypeError("reload()参数必须是一个模块") reload()参数必须是一个模块

如果你有一个像下面这样的导入,你可能需要使用sys。模块来获取你想要重载的模块:

  import importlib
  import sys

  from YYYY.XXX.ZZZ import CCCC
  import AAA.BBB.CC


  def reload(full_name)
    if full_name in sys.modules:
      importlib.reload(sys.modules[full_name])


  reload('YYYY.XXX.ZZZ') # this is fine in both cases
  reload('AAA.BBB.CC')  

  importlib.reload(YYYY.XXX.ZZZ) # in my case: this fails
  importlib.reload(AAA.BBB.CC)   #             and this is ok

主要的问题是进口。重载只接受模块而不接受字符串。