[Solved] ImportError:attempted relative import with no known parent package

Preface

In this article, I will analyze the cause of importerror: attached relative import with no known parent package exception. When you are running a python script. This exception may occur when a package is referenced in a relative reference mode (similar to Import.. module )

Let’s take a look at an example of this exception

Questions

Suppose you have the following directory structure:

project
├── config.py
└── demos
    ├── __init__.py
    └── demo.py

config.py contains some variables that should be used in demo.py

project/config.py

count = 5

project/demos/demo.py

from .. import config
print("The value of config.count is {0}".format(config.count))

When we try to run demo. Py , we encounter the following errors:

E:\project> python demos/demo.py
Traceback (most recent call last):
  File "demos/demo.py", line 1, in <module>
    from .. import config
ImportError: attempted relative import with no known parent package

The Python interpreter threw an exception without a parent package. Why

Let’s see how the Python interpreter parses the relevant modules. From PEP 328, we find an introduction to the relative imports :

Relative imports use a module’s __name__ attribute to determine that module’s position in the package hierarchy. If the module’s name does not contain any package information (e.g. it is set to __main__ ) then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.

Relative imports determine the module's location in the package hierarchy by using the module's __name__ attribute. If the module's name does not contain any package information (for example, it is set to __main__), then the relative reference assumes that this module is the top-level module, regardless of the module's actual location on the filesystem.

In other words, the algorithm for solving the module is based on the value of the __name__sum __package__variable. Most of the time, these variables do not contain any package information—for example, when  __name__=  __main__ and  __package__ =  None , the python interpreter does not know which package the module belongs to. In this case, relative references will consider this module to be the top-level module, regardless of the actual location of the module on the file system.

To demonstrate this principle, let’s update the code:

project/config.py

print('__file__={0:<35} | __name__={1:<20} | __package__={2:<20}'.format(__file__,__name__,str(__package__)))
count = 5

project/package/demo.py

print('__file__={0:<35} | __name__={1:<20} | __package__={2:<20}'.format(__file__,__name__,str(__package__)))
from .. import config
print("The value of config.count is {0}".format(config.count))

Try running it again and you will get the following output:

E:\project> python demos/demo.py
__file__=demos/demo.py      | __name__=__main__    | __package__=None
Traceback (most recent call last):
  File "demos/demo.py", line 3, in <module>
    from .. import config
ImportError: attempted relative import with no known parent package

As we can see, the Python interpreter does not have any information about the package to which the module belongs ( 0)__ name__=__ main__ and __ package__ = none ), so it throws an exception that the parent package cannot be found

Solution 1

we create a new empty in it__ init__. Py file to convert the project directory into a package

we create a file main. Py in the parent directory of the project directory

toplevel
├── main.py
└── project
  ├── __init__.py
  ├── config.py
  └── demos
      ├── __init__.py
      └── demo.py

toplevel/main.py

print('__file__={0:<35} | __name__={1:<20} | __package__={2:<20}'.format(__file__,__name__,str(__package__)))
import project.demos.demo

Execute the new example, and the output is as follows:

E:\toplevel>python main.py
__file__=main.py                             | __name__=__main__             | __package__=None
__file__=E:\toplevel\project\demos\demo.py   | __name__=project.demos.demo   | __package__=project.demos
__file__=E:\toplevel\project\config.py       | __name__=project.config       | __package__=project
The value of config.count is 5

Importing project.demos.demo in main. Py will set the package information of relative reference ( main. Py )__ name__ and __ package__ variable). Now, the Python interpreter can successfully resolve the relative references in project/demos/demo. Py

Solution 2

we create a new empty project in the Project folder__ init__. Py to convert the Project directory into a package

in the top level directory, use the - M parameter to call the Python interpreter to execute project.demos.demo [1]

toplevel
└── project
  ├── __init__.py
  ├── config.py
  └── demos
      ├── __init__.py
      └── demo.py

Again:

E:\toplevel>python -m project.demos.demo
__file__=E:\toplevel\project\demos\demo.py   | __name__=__main__        | __package__=project.demos
__file__=E:\toplevel\project\config.py       | __name__=project.config  | __package__=project
The value of config.count is 5

Running this command will automatically set the package information ( 0__ package__ variable). Now, the Python interpreter can successfully resolve the relative references in project/demos/demo. Py (even think that project/demos/demo__ name __=__ main__).

Note that when using the - M parameter, the executable file specified later has no . Py suffix

Note 2:

Another error that may be reported in actual use is the wrong path to execute the code

E:\toplevel>python -m project.demos.demo

Be sure to execute this command in the directory above the project

Similar Posts: