Reputation: 155
I am trying to import modules from a list. This would be to allow easier editing of imported modules, cleaner error message, and better error handling. Here is basically what I am trying to do:
imports = ['sys', 'itertools', 'datetime', 'os']
for x in imports:
try:
import x
print "Successfully imported ", x, '.'
except ImportError:
print "Error importing ", x, '.'
The issue here is that it tries importing x, not the value x should hold. I realize that to import from the list I could do something like below, but I do not see a way to handle the errors with it:
imports = ['sys', 'itertools', 'datetime', 'os']
modules = map(__import__, imports)
Is there a way to integrate the error handling with this method or should I try a different approach?
Upvotes: 14
Views: 14993
Reputation: 31508
This works with pesky pseudo submodules like lxml.etree
:
# PyPI imports
import pkg_resources, subprocess, sys
modules = {'lxml.etree', 'pandas', 'screeninfo'}
required = {m.split('.')[0] for m in modules}
installed = {pkg.key for pkg in pkg_resources.working_set}
missing = required - installed
if missing:
subprocess.check_call([sys.executable, '-m', 'pip', 'install', '--upgrade', 'pip'])
subprocess.check_call([sys.executable, '-m', 'pip', 'install', *missing])
for module in set.union(required, modules):
globals()[module] = __import__(module)
Tests:
print(pandas.__version__)
print(lxml.etree.LXML_VERSION)
Upvotes: 0
Reputation:
Instead of mapping them to ___import__
all at once, just append each module to the list modules
one at a time inside the for-loop:
imports = ['sys', 'itertools', 'datetime', 'os']
modules = []
for x in imports:
try:
modules.append(__import__(x))
print "Successfully imported ", x, '.'
except ImportError:
print "Error importing ", x, '.'
Note however that most Python programmers prefer the use of importlib.import_module
rather than __import__
for this task.
Note too that it might be better to make modules
a dictionary instead of a list:
imports = ['sys', 'itertools', 'datetime', 'os']
modules = {}
for x in imports:
try:
modules[x] = __import__(x)
print "Successfully imported ", x, '.'
except ImportError:
print "Error importing ", x, '.'
Now, instead of by index:
modules[0].version
modules[3].path
you can access the modules by name:
modules["sys"].version
modules["os"].path
Upvotes: 12
Reputation: 476
you can import programatically achieving the same effect as import module as module_shortname
by using globals()
:
packages_to_import = [{'name': 'numpy', 'as': 'np'},
{'name': 'pandas', 'as': 'pd'}]
for package in packages_to_import:
package_name = package['name']
import_as = package.get('as', package_name)
globals()[import_as] = __import__(package_name)
print(np.version.full_version)
print(pd.__version__)
Upvotes: 3
Reputation: 1211
None of the most voted options worked for me. They seemed to be imported successfully, but I couldn't use them later. In case you experienced the same issue, this tutorial solved it for me.
modules = ['sys', 'itertools', 'datetime', 'os']
for lib in modules:
globals()[lib] = __import__(lib)
PS: I guess they were not added to my global variables before
Upvotes: 4
Reputation: 1037
This worked for me on Python 3.7
modules = ["sys","os","platform","random","time","functools"]
for library in modules:
try:
exec("import {module}".format(module=library))
except Exception as e:
print(e)
print(sys.argv)
Importing a submodule:
modules = ["PyQt5"] # pip install PyQt5
submodules = ["QtCore"]
for library in modules:
for sublibrary in submodules:
try:
exec("from {m} import {s}".format(m=library, s=sublibrary))
except Exception as e:
print(e)
print(dir()) # Includes QtCore
print(dir(QtCore)) # All functions, classes and variables are exactly correct as with "from PyQt5 import QtCore"
Importing everything:
modules = ["sys","os","platform","random","time","functools"]
for library in modules:
try:
exec("from {module} import *".format(module=library))
except Exception as e:
print(e)
print(dir()) # Exactly working as thought
Importing a instance or something:
modules = ["PyQt5"] # pip install PyQt5
submodules = ["QtCore"]
func = ["QCoreApplication"]
for library in modules:
for f in func:
for sublibrary in submodules:
try:
exec("from {m}.{s} import {f}".format(m=library, s=sublibrary, f=f))
except Exception as e:
print(e)
print(dir()) # Includes QCoreApplication instance
Importing everything from a modules's submodule:
modules = ["PyQt5"] # pip install PyQt5
submodules = ["QtCore"]
for library in modules:
for sublibrary in submodules:
try:
exec("from {m}.{s} import *".format(m=library, s=sublibrary)) # Didn't mention f"" strings all the times. But for beginners .format is better.
except Exception as e:
print(e)
print(dir()) # Includes all PyQt5.QtCore stuff
Upvotes: 1
Reputation: 50550
You can modify your import x
line to use the __import__(x)
format
imports = ['sys', 'itertools', 'datetime', 'os','doesntexit']
for x in imports:
try:
__import__(x)
print "Success"
except ImportError:
print "Error ", x
Outputs:
Success
Success
Success
Success
Error doesntexit
Upvotes: 0