How to Unimport a Python Module Which Is Already Imported

Python: import function from an already imported module

The Python import system just doesn't work that way. When you do from foo import bar, foo has to be a "real", fully-qualified package or module name (or a relative one using dots). That is, it has to be something that you could use in a plain import foo. It can't just be a module object you have lying around. For instance, you also can't do this:

import foo as bar
from bar import someFunction

This is stated in the documentation, although you have to read through that section to get the full picture. It says:

Import statements are executed in two steps: (1) find a module, and initialize it if necessary; (2) define a name or names in the local namespace (of the scope where the import statement occurs). The statement comes in two forms differing on whether it uses the from keyword. The first form (without from) repeats these steps for each identifier in the list. The form with from performs step (1) once, and then performs step (2) repeatedly.

Step (1) is "finding the module", and if you read on you will see that this is the process where it looks in sys.modules, sys.path, etc. There is no point at which it looks for a name in the importing namespace that happens to have a module object as its value. Note that the module-finding process is no different for the two kinds of imports; the way it finds foo when you do import foo is the same way it finds it when you do from foo import bar. If a plain import my_module would not work (as in your example), then from my_module import stuff won't work either.

Note that if you already imported the module and just want a shorter name for a function inside it, you can just assign a regular variable to the function:

from my_package import my_module
myfunc = my_module.my_function

Remove an imported python module

Unloading a module from Python is not supported.

Do you have to reimport external modules when they have been already imported in an other imported module?

import can do two things:

  1. Create a module
  2. Define a new variable in the current scope bound to a module

A module foo will only be created once per process, no matter how many times import foo is executed. However, import foo will always bind the module to the name foo, even if foo is already bound (to that module or some other value) in the current scope.

import numpy as np binds the name np to the numpy module in the global scope of mod1.

import mod1 only binds the name mod1; it does not bring the global variables of mod1 into the global scope of mod2. For that, you would need something like

from mod1 import np

or just use mod1.np in mod2.

What you appear to be looking for is a way to put np into a process-wide namespace, accessible from any module. Python only has one such namespace, the built-in namespace, but you cannot add names to that. You only have the individual module-global namespaces.

Above, I mentioned that a module is only created once. This is because import will first check if the requested module already exists in sys.modules. You could access np from anywhere after it's been imported once with

sys.modules['numpy']  # The "real" name, not the import-defined alias

However, there's no guarantee that numpy has been defined yet, and you still have to import sys to get access to sys.modules, so this doesn't gain you anything over simply using

import numpy as np

wherever you want np.

How do I unload (reload) a Python module?

You can reload a module when it has already been imported by using importlib.reload():

from importlib import reload  # Python 3.4+
import foo

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

In Python 2, reload was a builtin. In Python 3, it was moved to the imp module. In 3.4, imp was deprecated in favor of importlib. When targeting 3 or later, either reference the appropriate module when calling reload or import it.

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.

To quote from the docs:

  • Python module’s code is recompiled and the module-level code re-executed, defining a new set of objects which are bound to names in the module’s dictionary by reusing the loader which originally loaded the module. The init function of extension modules is not called a second time.
  • As with all other objects in Python the old objects are only reclaimed after their reference counts drop to zero.
  • 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.

How to import a module in Python which is already imported in another file?

In general, you shouldn't import stuff from a module which itself has only imported it:

# gui.py
from PyQt5 import QtCore, QtGui, QtWidgets

def some_function():
pass

you should then do:

# main.py
from PyQt5 import QtCore, QtGui, QtWidgets
from gui import some_function

The only exception are __init__.py files that aggregate modules from its submodules for convenience reasons:

# some_module/__init__.py
from .submodule import some_function
from .other_submodule import some_other_function

and then

# main.py
from .some_module import some_function, some_other_function

Since the're not modules that are provided by gui you should just import them directly from PyQt5.

Run python script with module/ modules already imported

I think what you'r looking for is the interactive mode:

-i
When a script is passed as first argument or the -c option is used, enter interactive mode after executing the script or the command

So just use python -i cls.py in your batch file. This would import your Python file and stay in the Python interpreter prompt. You could then just call cls() because it's already imported.

Alternatively, you could set the environment variable PYTHONSTARTUP in your batch file:

If this is the name of a readable file, the Python commands in that file are executed before the first prompt is displayed in interactive mode. The file is executed in the same namespace where interactive commands are executed so that objects defined or imported in it can be used without qualification in the interactive session.

How can I check if a module has been imported?

Test for the module name in the sys.modules dictionary:

import sys

modulename = 'datetime'
if modulename not in sys.modules:
print 'You have not imported the {} module'.format(modulename)

From the documenation:

This is a dictionary that maps module names to modules which have already been loaded.

Note that an import statement does two things:

  1. if the module has never been imported before (== not present in sys.modules), then it is loaded and added to sys.modules.
  2. Bind 1 or more names in the current namespace that reference the module object or to objects that are members of the module namespace.

The expression modulename not in sys.modules tests if step 1 has taken place. Testing for the result of step 2 requires knowing what exact import statement was used as they set different names to reference different objects:

  • import modulename sets modulename = sys.modules['modulename']
  • import packagename.nestedmodule sets packagename = sys.modules['packagename'] (no matter how many addional levels you add)
  • import modulename as altname sets altname = sys.module['modulename']
  • import packagename.nestedmodule as altname sets altname = sys.modules['packagename.nestedmodule']
  • from somemodule import objectname sets objectname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulename sets nestedmodulename = sys.modules['packagename.nestedmodulename'] (only when there was no object named nestedmodulename in the packagename namespace before this import, an additional name for the nested module is added to the parent package namespace at this point)
  • from somemodule import objectname as altname sets altname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulename as altname sets altname = sys.modules['packagename.nestedmodulename'] (only when there was no object named nestedmodulename in the packagename namespace before this import, an additional name for the nested module is added to the parent package namespace at this point)

You can test if the name to which the imported object was bound exists in a given namespace:

# is this name visible in the current scope:
'importedname' in dir()

# or, is this a name in the globals of the current module:
'importedname' in globals()

# or, does the name exist in the namespace of another module:
'importedname' in globals(sys.modules['somemodule'])

This only tells you of the name exists (has been bound), not if it refers to a specific module or object from that module. You could further introspect that object or test if it’s the same object as what’s available in sys.modules, if you need to rule out that the name has been set to something else entirely since then.

Python - How to remove/unimport libs was imported before

__future__ looks like a module but isn't really. Importing it actually affects the compilation options of the current module. There's no way to "undo" it, since it effectively happens before the module is even executed.

If it were any other "normal" module, there are ways, but you're out of luck here.
Either deal with the changed semantics, or put the code that needs different compilation in a separate module.



Related Topics



Leave a reply



Submit