I have a package i'm working on which i have also installed into site-packages
. (I've installed my own package using pip
)
How does Python know to import from the "local" code (the code i'm working on), rather than importing from site-packages
? I'm asking because i want to better understand and i'm worried that somehow i might import code from site-packages
when i really want to use my own (latest) code
It’s confusing to me that this is not more clear in how we write imports. It seems to me that the programmer doesn’t know if she is importing her own code or importing from site-packages
. Am i missing something here?
One thought i had was to use relative imports but if i understand they are not recommended in general
I'm using Python 3.8.5
Python's import
mechanism (commonly referred as the import machinery) is based on Finders and Loaders. When you import a module using the import statement, a series are finders try to find the module that you are importing. You can see the list of all finders that are triggered in order by:
>>> import sys
>>> sys.meta_path
[<class '_frozen_importlib.BuiltinImporter'>,
<class '_frozen_importlib.FrozenImporter'>,
<class '_frozen_importlib_external.PathFinder'>]
If none of the finders are able to resolve the module, then ModuleNotFoundError
is raised.
BuiltinImporter
resolves modules like sys, time, gc etc which are preloaded into the interpreter. FrozenImporter
resolves frozen modules. PathFinder
resolves modules by going through the paths in sys.path
.
Printing sys.path
shows that your current directory is the first entry and hence is searched for a match first.
Here's a simple sequence you can use to reason about where the import is going to happen from:
import sys
. Even if you have a file named sys.py in your current directory, since BuiltinImporter
is called first, it will resolve the built-in sys module.sys.path
.Modules that are imported by PathFinder (ones present in sys.path) will have __path__
as an attribute that you can check to see where it is located.
It is also possible to reorder the finders in sys.meta_path or even add your own custom finders and loaders giving you full control and creativity to modify the default machinery. Custom finders and loaders can be registered to look for modules elsewhere in the system or even dynamically from external systems.