Adding a bit of sophistication to the existing answers....
Depending on the use case, it may be somewhat inconvenient to have to explicitly specify the full path [E.g. package.subpackage.module...
] of the class/method you want to import. On top of importlib, we can leverage __init__.py
to make things even cleaner.
Let's say I have a python package, like so:
├── modes
│ ├── __init__.py
│ ├── bar.py
│ ├── foo.py
│ ├── modes.py
foo.py
, say, have some class/functions we'd like to use somewhere else in our program:
from modes.modes import Mode
class Foo[Mode]:
def __init__[self, *arg, **kwargs]:
super[Foo, self].__init__[*arg, **kwargs]
def run[self]:
self.LOG.info[f"This is FOO!"]
With a command line argument, I can pass an argument that corresponds to a mode that I want to run. I'd like to be able to so something like this:
def set_mode[mode]:
""" """
import importlib
module = importlib.import_module['modes.foo']
getattr[module, mode][].run[]
which outputs:
>> set_mode["Foo"]
>> engine_logger:INFO - This is FOO!
That works fine, however what we'd REALLY want to get at is this:
def set_mode[mode]:
""" """
import importlib
module = importlib.import_module['modes'] # only import the package, not modules explicitely
getattr[module, mode][].run[]
Which raises an error:
>> set_mode["Foo"]
>> AttributeError: module 'modes' has no attribute 'Foo'
However, we can add the following to /modes/__init__.py
:
from .foo import Foo
from .bar import Bar
Then, we can do:
>> set_mode["Foo"]
>> engine_logger:INFO - This is FOO!
>> set_mode["Bar"]
>> engine_logger:INFO - This is BAR!
In other worlds, all sub modules/functions/classes we import in init.py will be found directly with importlib.import_module[...], without having to specify the full path from outside.
View Discussion
Improve Article
Save Article
View Discussion
Improve Article
Save Article
Python provides a feature to create and store classes and methods and store them for further use. The file containing these sets of methods and classes is called a module. A module can have other modules inside it.
Note: For more information, refer to Python Modules
Example: A simple example of importing a module is shown below in which, there are 2 files that are module.py and importing_mod.py in the same directory. The module.py file acts as a module to import_mod.py file.
module.py
def
welcome[
str
]:
print
[
"Hi ! % s Welcome to GfG"
%
str
]
import_mod.py file
import
module as mod
mod.welcome[
"User_1"
]
Output
Hi! User_1 Welcome to GfG
Dynamically Loading Modules or Classes
The modules added in the above code are importing modules statically i.e in compile time. In Python we can import modules dynamically by two ways
- By using __import__[] method:
__import__[]
is a dunder method [methods of class starting and ending with double underscore also called magic method] and all classes own it. It is used to import a module or a class within the instance of a class. There is an example on this method given as follows, in which we will be importing a module dynamically. The module file is now modified as:module.py
class
Welcome:
def
welcome[
str
]:
print
[
"Hi ! % s Welcome to GfG"
%
str
]
Dynamic_import.py
class
Dimport:
def
__init__[
self
, module_name, class_name]:
module
=
__import__
[module_name]
my_class
=
getattr
[module, class_name]
my_class.welcome[
'User_1'
]
obj
=
Dimport[
"module"
,
"Welcome"
]
Output
Hi! User_1 Welcome to GfG
- Using the imp module: Modules can be imported dynamically by the imp module in python. The example below is a demonstration on the using the imp module. It provides the
find_module[]
method to find the module and theimport_module[]
method to import it.Dynamic_import.py
import
imp
import
sys
def
dynamic_imp[name, class_name]:
try
:
fp, path, desc
=
imp.find_module[name]
except
ImportError:
print
[
"module not found: "
+
name]
try
:
example_package
=
imp.load_module[name, fp,
path, desc]
except
Exception as e:
print
[e]
try
:
myclass
=
imp.load_module[
"% s.% s"
%
[name,
class_name],
fp, path, desc]
except
Exception as e:
print
[e]
return
example_package, myclass
if
__name__
=
=
"__main__"
:
mod, modCl
=
dynamic_imp[
"GFG"
,
"addNumbers"
]
modCl.addNumbers[
1
,
2
]
Output
Hi! User_1 Welcome to GfG