While you can put simple projects in a single file, most Python development projects will require multiple files to keep them manageable. That means you need a way to import one file into another. However, many Pythonistas find importing files confusing. Fortunately, it is easy if you know the difference between the various Python import statements.
What is Importing?
Importing refers to allowing a Python file or a Python module to access the script from another Python file or module. You can only use functions and properties your program can access. For instance, if you want to use mathematical functionalities, you must import the math package first. This is because you must define everything you want to use in Python before you use them.
For example, Python would give a NameError
for the following code:
myPi = math.pi
This is because neither the math
object nor its properties and methods are natively available to the language itself. To use the math
object, you must import it first.
import math
myPi = math.pi
print myPi
The import
statement adds the object to the current scope of your program.
How Imports Work
The import
statements do a lot under the hood to import file or module. First, they look for your module or package in sys.modules
, where Python stores your previously imported code. If Python cannot find the module there, it will then search through the Python Standard Library for it. If Python still cannot find the module, it will go through your entire storage space, starting with the current directory and the ones listed in your system.path
. If the module is found in these places, it will add the module to your program, otherwise, it will give a ModuleNotFoundError
.
Import Statement Syntax
To import a module directly you just put the name of the module or package after the import
keyword. Please note that this statement is case sensitive.
import mymodule
However, Python does offer a more sophisticated syntax for importing code. This second format includes the from
keyword as well.
from mypackage import mymodule
In this format, you specify both the module or code you want along with where it is. You put the name of your code, module, or subpackage for mymodule
, and its location for mypackage
. Such an import statement is great if you only want to import some of the code from the mentioned package, and not the package itself.
You can even rename the module by including the as
keyword.
import mymodule as oMyFunction
You can also use the asterisk (*
) as a wild card. The following statement will import every function and property contained in the math
package.
from math import *
Regardless of the syntax, you should always follow the recommended importing best practices.
Absolute Imports
Absolute imports include the entire path to your script, starting with the program's root folder. While you must separate each folder by a period, you can have it be as long as you need it.
The following are examples of absolute imports:
from package1.firstmodule import firstmodule
import package1.secondmodule.myfunction
Absolute Import Advantages and Disadvantages
Unlike other languages, most Python developers prefer using absolute imports over their relative cousins. This is because absolute imports make it really clear what you are trying to do. The actual location of your files is right there in your code. In fact, you can use them anywhere in your code. They will just work.
Absolute imports can get quite long though. If your project has sub packages in sub packages in sub packages, your import statements can expand beyond a single line of code. When that happens, you are much better off using relative imports instead.
You also may discover an issue when you start your program using different startup files. The Python interpreter only declares the starting file's current folder as its sys.path
package root. This is fine if you only load your program using files from the root folder. This is because sys.path
will remain static throughout your script.
However, the situation changes when you start your program from a subfolder, or in any other situation where your sys.path
may change. Then, your "root folder" is the subfolder. Because you cannot use implicit imports (as we will see below), any file outside the subfolder becomes inaccessible to your program.
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
You have two workarounds for this. You can either start your subfolder script as an imported module or you can append sys.path
directly in your code.
For example:
- Importing modules as run time:
python -m packA.a2
- Append sys.path before importing your files:
import os, sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
from packA.subA import sa2
Relative Imports
With relative imports, you only specify where your resources are relative to the current code file. You can do this either implicitly or explicitly, even though implicit relative imports were removed in Python 3.
As for the syntax, relative imports make use of dot notation. Single dots represent the directory of the current script. Two dots represent the parent folder. Thress dots mean the grandparent, and so forth. You might be familiar with this system if you use a UNIX-like operating system or the Windows console.
The following are examples of relative imports:
- Explicit imports
import other
from . import some_class
from .subA import sa1
- Implicit imports
from .some_module import some_class
import some_function
import subA.sa1
Relative Imports and their Advantages and Disadvantages
Relative imports rarely grow as long as absolute imports. They can even turn a ridiculously long absolute statement into something as simple as:
from ..my_sub_package.my_module import my_function
However, they also hide the paths to your modules. This might be okay if you are the only developer, but it gets messy if you are a part of a development team where the actual directory structure can change.
Which Import to Use?
Unless you are working on a large project with several layers of sub-packages, you should always use absolute imports. That way, your code will be easily understood by anyone that looks at it, including yourself if you got back to it to update it later. Even if you do have long paths, you should still try to write your program to only use absolute statements to simplify your code and your life.
Conclusion
Like any other modern programming language, Python allows you to import code from other files or modules. However, this can turn in to a confusing and error-prone process, unless you understand the concepts behind the import system.
In this article we looked at the various ways of importing code in to our Python programs, including absolute and relative imports. We also compared the pros and cons of each, which have their advantages in different use-cases.