148

How do I check if I imported a module somewhere in the code?

 if not has_imported("somemodule"):
     print('you have not imported somemodule')

The reason that I would like to check if I already imported a module is because I have a module that I don't want to import, because sometimes it messes up my program.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
yuval
  • 2,848
  • 4
  • 31
  • 51
  • 1
    Just put `raise SystemError()` (or other exception of your choice) at the top of the module you don't want to import. If you *do* actually import it somewhere, your program will throw a traceback and exit. – larsks May 27 '15 at 13:01
  • How does just importing a module mess up your program anyway? Doesn't sound so likely. – Bill Woodger May 27 '15 at 13:09
  • 1
    @BillWoodger: perhaps that module [changes global state you don't want changing](https://stackoverflow.com/questions/23918716/reloading-a-module-gives-functionality-that-isnt-originally-available-by-import/23918750#23918750). – Martijn Pieters May 27 '15 at 13:12
  • @MartijnPieters Yoiks. And import sounds so neutral. – Bill Woodger May 27 '15 at 14:04
  • 1
    Possible duplicate of [how to test if one python module has been imported?](http://stackoverflow.com/questions/5027352/how-to-test-if-one-python-module-has-been-imported) – shadowtalker Apr 20 '16 at 02:39

5 Answers5

201

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.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    Is this the best way to check for a required package inside a function? That is, say some function requires `numpy` package - is using `import sys` inside the function the best to check that it has been imported? By "best" I mean in term of the performance impact as `import sys` will be then called each time the function is called. Thank you – Confounded Dec 02 '19 at 17:10
  • 1
    @Confounded you can simply import sys outside of the function if that worries you. Not that `import sys` is in any way expensive; `sys` always exists, it is by default already loaded. But for an optional package: *just import the package*. Catch the `ImportError` exception if the package is not installed, and set a flag indicating it is installed when the import succeeds. After that you can use the flag to inform your use of the optional dependency. – Martijn Pieters Dec 02 '19 at 23:39
  • How to check if sys is imported? – Fisher Oct 06 '21 at 14:01
  • @Fisher: you don't. `sys` is always active. If you need to know if `sys` was imported into the current global namespace, you could check if the name `sys` exists, but I don't see any point in that. – Martijn Pieters Oct 29 '21 at 12:44
44

To the sys.modules answers accepted, I'd add one caveat to be careful about renaming modules on import:

>>> import sys
>>> import datetime as dt
>>> 'dt' in sys.modules
False
>>> 'datetime' in sys.modules
True
morvan68
  • 612
  • 6
  • 8
22

Use sys.modules to test if a module has been imported (I'm using unicodedata as an example):

>>> import sys
>>> 'unicodedata' in sys.modules
False
>>> import unicodedata
>>> 'unicodedata' in sys.modules
True
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Haresh Shyara
  • 1,826
  • 10
  • 13
10

sys.modules contains all modules used anywhere in the current instance of the interpreter and so shows up if imported in any other Python module.

dir() checks whether the name was defined in the current namespace.

The combination of the two is safer than each separate and works as long you didn't define a copy yourself.

if ('copy' in sys.modules) and ('copy' in dir()):
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
HansW
  • 101
  • 1
  • 3
6

Use:

if "sys" not in dir():
  print("sys not imported!")

This works well at the beginning (top) of the code, but it should be carefully used, in case another object with name sys is created.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rundekugel
  • 1,118
  • 1
  • 10
  • 23
  • That only checks whether the module was imported in the current namespace. Also `sys` can be anything, not just a module. – vaultah Nov 20 '17 at 12:13
  • There's a problem with this answer - if you import module `as` some name - the name you choose will appear there; For example - `import numpy as np` - `dir()` will contain `np` and not `numpy` – noamgot Mar 13 '23 at 10:56