I have the following directory:
mydirectory ├── __init__.py ├── file1.py └── file2.py
I have a function f defined in file1.py.
If, in file2.py, I do
from .file1 import f
I get the following error:
SystemError: Parent module '' not loaded, cannot perform relative import
Why? And how to make it work?
Here is the solution which works for me: I do the relative imports as from .. sub2 import mod2 and then, if I want to run mod1.py then I go to the parent directory of app and run the module using the python -m switch as python -m app. sub1.
With your new skills, you can confidently import packages and modules from the Python standard library, third party packages, and your own local packages. Remember that you should generally opt for absolute imports over relative ones, unless the path is complex and would make the statement too long.
If you have setup.py in your project and you use find_packages() within it, it is necessary to have an __init__.py file in every directory for packages to be automatically found.
The __init__.py file makes Python treat directories containing it as modules. Furthermore, this is the first file to be loaded in a module, so you can use it to execute code that you want to run each time a module is loaded, or specify the submodules to be exported.
Launching modules inside a package as executables is a bad practice.
When you develop something you either build a library, which is intended to be imported by other programs and thus it doesn't make much sense to allow executing its submodules directly, or you build an executable in which case there's no reason to make it part of a package.
This is why in setup.py
you distinguish between packages and scripts. The packages will go under site-packages
while the scripts will be installed under /usr/bin
(or similar location depending on the OS).
My recommendation is thus to use the following layout:
/ ├── mydirectory | ├── __init__.py | ├── file1.py └── file2.py
Where file2.py
imports file1.py
as any other code that wants to use the library mydirectory
, with an absolute import:
from mydirectory.file1 import f
When you write a setup.py
script for the project you simply list mydirectory
as a package and file2.py
as a script and everything will work. No need to fiddle with sys.path
.
If you ever, for some reason, really want to actually run a submodule of a package, the proper way to do it is to use the -m
switch:
python -m mydirectory.file1
This loads the whole package and then executes the module as a script, allowing the relative import to succeed.
I'd personally avoid doing this. Also because a lot of people don't even know you can do this and will end up getting the same error as you and think that the package is broken.
Regarding the currently accepted answer, which says that you should just use an implicit relative import from file1 import f
because it will work since they are in the same directory:
This is wrong!
file1
module (since it will be imported instead of your module!).Even if it works the file1
will not be seen as part of the mydirectory
package. This can matter.
For example if file1
uses pickle
, the name of the package is important for proper loading/unloading of data.
When launching a python source file, it is forbidden to import another file, that is in the current package, using relative import.
In documentation it is said:
Note that relative imports are based on the name of the current module. Since the name of the main module is always "__main__", modules intended for use as the main module of a Python application must always use absolute imports.
So, as @mrKelley said, you need to use absolute import in such situation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With