Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
464 views
in Technique[技术] by (71.8m points)

python - 如何卸载(重新加载)模块?(How do I unload (reload) a module?)

I have a long-running Python server and would like to be able to upgrade a service without restarting the server.

(我有一台运行时间较长的Python服务器,并且希望能够在不重新启动服务器的情况下升级服务。)

What's the best way do do this?

(最好的方法是什么?)

if foo.py has changed:
    unimport foo  <-- How do I do this?
    import foo
    myfoo = foo.Foo()
  ask by Mark Harrison translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can reload a module when it has already been imported by using the reload builtin function:

(您可以使用内置的reload内置函数reload导入已导入的模块:)

from importlib import reload  # Python 3.4+ only.
import foo

while True:
    # Do some things.
    if is_changed(foo):
        foo = reload(foo)

In Python 3, reload was moved to the imp module.

(在Python 3中, reload已移至imp模块。)

In 3.4, imp was deprecated in favor of importlib , and reload was added to the latter.

(在3.4中,不推荐使用imp而支持importlib ,并将reload添加到后者中。)

When targeting 3 or later, either reference the appropriate module when calling reload or import it.

(如果定位到3或更高版本,则在调用reload或导入它时参考相应的模块。)

I think that this is what you want.

(我认为这就是您想要的。)

Web servers like Django's development server use this so that you can see the effects of your code changes without restarting the server process itself.

(诸如Django开发服务器之类的Web服务器都使用此功能,这样您就可以看到代码更改的效果,而无需重新启动服务器进程本身。)

To quote from the docs:

(引用文档:)

Python modules' code is recompiled and the module-level code reexecuted, defining a new set of objects which are bound to names in the module's dictionary.

(重新编译Python模块的代码并重新执行模块级代码,从而定义了一组新对象,这些对象绑定到模块字典中的名称。)

The init function of extension modules is not called a second time.

(扩展模块的init函数不会被第二次调用。)

As with all other objects in Python the old objects are only reclaimed after their reference counts drop to zero.

(与Python中的所有其他对象一样,旧对象仅在其引用计数降至零后才被回收。)

The names in the module namespace are updated to point to any new or changed objects.

(模块名称空间中的名称将更新为指向任何新的或更改的对象。)

Other references to the old objects (such as names external to the module) are not rebound to refer to the new objects and must be updated in each namespace where they occur if that is desired.

(对旧对象的其他引用(例如模块外部的名称)不会反弹以引用新对象,并且如果需要的话,必须在出现它们的每个命名空间中进行更新。)

As you noted in your question, you'll have to reconstruct Foo objects if the Foo class resides in the foo module.

(正如您在问题中指出的那样,如果Foo类位于foo模块中,则必须重新Foo对象。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...