Everyone knows and loves Python’s import
function. This function is used to import external modules into the current module/script we are writing. Here are a few simple examples illustrating how the function can be used:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# import a specific module | |
from vehicle.four_wheels import car | |
my_car = car.Car(transmission="automatic") | |
# import a specific class within a module | |
from vehicle.four_wheels.car import Car | |
my_car = Car(transmission="automatic") | |
# import everything from a module into the current namespace | |
from vehicle.four_wheels import * | |
my_car = Car(transmission="automatic") | |
my_bus = Bus(color="Yellow") |
Internally, a call to the import
function makes a call to the built-in __import__
function. However, there are 2 cases where using import
would not work and the only way out is to call __import__
ourselves.
The most common case where we would have to call __import__
directly would be when we want to import specific modules at run-time based on user input. Here is how we might do that:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# global scope these variables so that | |
# we can use them throughout our code | |
Car = None | |
Bus = None | |
# | |
# exciting stuff happening here | |
# | |
# now, based on the variable vehicle | |
# we want to import a specific module | |
if vehicle == "car": | |
# equivalent to: from vehicle.four_wheels.car import Car | |
_Car = __import__("vehicle.four_wheels.car", globals(), locals(), ["Car"]) | |
Car = _Car.Car | |
if vehicle == "bus": | |
# equivalent to: from vehicle.four_wheels.bus import Bus | |
_Bus = __import__("vehicle.four_wheels.bus", globals(), locals(), ["Bus"]) | |
Bus = _Bus.Bus | |
Yes, I know that we didn’t really have to import at run-time in the previous example. It was just meant to be a simple example 🙂
Another case where we might have to call __import__
is when, for some reason, the parent modules/folders for a module we want to import or a module itself has a name with characters that are not allowed by Python. For example, something like the snippet below would not work:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# this does not work! | |
from vehicles.four–wheels.car import Car |
Notice how the hyphen is not allowed in the module name. Here is how we might work around that:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# this works! | |
_Car = __import__("vehicles.four-wheels-car", globals(), locals(), ["Car"]) | |
Car = _Car.Car |