Relative imports in Python 3 not working

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 imports

Why? And how to make it work?

+52
python import module relative
May 19 '13 at 17:28
source share
4 answers

since file1 and file2 are in the same directory, you don’t even need to have the __init__.py file. If you are going to zoom in, leave it there.

To import something into a file in the same directory, just do it

from file1 import f

ie, you do not need to do the relative .file1 path, because they are in the same directory.

If your main function, script, or something else that will run the entire application is in a different directory, then you will need to do everything regarding where it is executed.

+24
May 19 '13 at 17:42
source share

Running modules inside a package as executable files is bad practice.

When you develop something, you either create a library that is intended to be imported by other programs, and therefore it makes no sense to allow the direct execution of your submodules or you create an executable file, in which case there is no reason to make it part of the package.

This is why in setup.py you distinguish between packages and scripts. Packages will be under site-packages , while scripts will be installed under /usr/bin (or a similar location depending on the OS).

My recommendation, therefore, should use the following layout:

 / β”œβ”€β”€ mydirectory | β”œβ”€β”€ __init__.py | β”œβ”€β”€ file1.py └── file2.py 

Where file2.py imports file1.py like any other code that wants to use the mydirectory library, with absolute import:

 from mydirectory.file1 import f 

When you write 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 mess with sys.path .

If you ever, for some reason, really want to run a package submodule, the correct way to do this is to use the -m switch:

 python -m mydirectory.file1 

Loads the entire package and then executes the module as a script, allowing relative imports to succeed.

I would personally avoid this. Also, because many people do not even know that you can do this, and in the end you will get the same error as you, and think that the package is broken.




Regarding the currently accepted answer, which says that you should use implicit relative imports from file1 import f , because it will work because they are in the same directory:

This is wrong !

  • It will not work in python3, where implicit relative imports will be prohibited and will certainly break if you install the file1 module (since it will be imported instead of your module!).
  • Even if it works, file1 will not be considered as part of the mydirectory package. It can make a difference.

    For example, if file1 uses pickle , the package name is important for the correct loading / unloading of data.

+42
Oct 18 '15 at 6:42
source share

When starting the python source file, it is forbidden to import another file located in the current package using relative import.

The documentation says:

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 to be used as the main module of a Python application should always use absolute imports.

So, as @mrKelley said, you need to use absolute imports in this situation.

+20
May 19 '13 at 17:45
source share
 myproject/ mypackage β”œβ”€β”€ __init__.py β”œβ”€β”€ file1.py β”œβ”€β”€ file2.py └── file3.py mymainscript.py 

Import example from one file to another

 #file1.py from myproject import file2 from myproject.file3 import MyClass 

Import the sample package into mainccript

 #mymainscript.py import mypackage 

https://docs.python.org/3/tutorial/modules.html#packages

https://docs.python.org/3/reference/import.html#regular-packages

https://docs.python.org/3/reference/simple_stmts.html#the-import-statement

https://docs.python.org/3/glossary.html#term-import-path

The sys.path variable is a list of strings that define the path to search for interpreters for modules. It is initialized by the default path taken from the PYTHONPATH environment variable or from the built-in default value if PYTHONPATH is not set. You can change it using standard list operations:

 import sys sys.path.append('/ufs/guido/lib/python') sys.path.insert(0, '/ufs/guido/myhaxxlib/python') 

Inserting it at the beginning has the advantage of ensuring that the path is searched over others (even built-in) in case of name conflicts.

0
Dec 17 '14 at 15:27
source share



All Articles