Coder Perfect

How do I unload (reload) a Python module?

Problem

I have a Python server that has been running for a long time, and I’d like to be able to upgrade a service without restarting the server. What’s the best method to go about doing this?

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

Asked by Mark Harrison

Solution #1

You can use importlib.reload() to reload a module that has already been imported:

from importlib import reload  # Python 3.4+
import foo

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

Reload was a built-in feature in Python 2. It was relocated to the imp module in Python 3. Imp was deprecated in favor of importlib in version 3.4. If you’re targeting 3 or later, either import or reference the proper module before using reload.

This, I believe, is what you desire. This is used by web servers like Django’s development server to allow you to observe the consequences of your code changes without having to restart the server process.

To quote the documents:

If the Foo class is in the foo module, you’ll have to recreate Foo objects, as you said in your inquiry.

Answered by 9 revs, 8 users 53%

Solution #2

imp.reload imp.reload imp.reload imp.reload imp.reload imp.reload imp.reload imp.reload imp.re (module)

This question has been answered by the BDFL.

However, with version 3.4, imp was deprecated in favor of importlib (thanks, @Stefan!).

As a result, I believe you’d now use importlib.reload(module), though I’m not certain.

Answered by Paul D. Waite

Solution #3

If the module isn’t pure Python, removing it can be very tough.

Here’s where you may learn more: How do I truly delete an imported module?

>>> import sys, empty, os
>>> sys.getrefcount(sys)
9
>>> sys.getrefcount(os)
6
>>> sys.getrefcount(empty)
3
>>> del sys.modules["empty"]
>>> del empty

Answered by Gregg Lind

Solution #4

reload(module), but only if the module is totally self-contained. If anything else has a reference to the module (or any object that belongs to the module), you’ll get strange and subtle problems as a result of the old code lingering longer than you planned, and things like isinstance not working across various versions of the same code.

You must also reload all modules that depend on the reloaded module to remove all references to the old code if you have one-way dependencies. Then, recursively, reload modules that rely on the reloaded modules.

If you have circular dependencies, which is fairly common when reloading a package, you must unload all of the modules in the group at the same time. This is impossible with reload() because it re-imports each module before its dependencies have been updated, allowing old references to seep into new modules.

In this instance, the only method to achieve it is to hack sys.modules, which is rather unsupported. You’d have to go through and delete each sys.modules entry you didn’t want to be reloaded on the next import, as well as any entries whose values are no longer valid. There isn’t any to deal with a bug in the implementation that involves caching unsuccessful relative imports. It’s not ideal, but as long as you have a completely self-contained set of dependencies that don’t leave any references outside of the codebase, it’ll suffice.

It’s generally best if the server is restarted. 🙂

Answered by bobince

Solution #5

Use the built-in reload method in Python 2:

reload(module)

Use reload from module imp: for Python 2 and Python 3.2—3.3.

import imp
imp.reload(module)

Imp has been deprecated in favor of importlib since Python 3.4, therefore use this instead:

import importlib
importlib.reload(module)

or:

from importlib import reload
reload(module)

TL;DR:

importlib.reload importlib.reload importlib.reload importlib.reload importlib.reload importlib.re (module) imp.reload imp.reload imp.reload imp.reload imp.reload imp.reload imp.reload imp.re (module) reload in Python 2 (module)

Answered by goetzc

Post is based on https://stackoverflow.com/questions/437589/how-do-i-unload-reload-a-python-module