Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multilevel relative import

Multilevel relative import

I have following folder structure

top\
   __init__.py
   util\
      __init__.py
      utiltest.py
   foo\
      __init__.py
      foo.py
      bar\
         __init__.py
         foobar.py

I want to access from foobar.py the module utiltest.py. I tried following relative import, but this doesn't work: from ...util.utiltest import *

I always get ValueError: Attempted relative import beyond toplevel package

How to do such a multileve relative import?

like image 480
Razer Avatar asked Feb 14 '12 12:02

Razer


People also ask

What is a relative import?

A relative import specifies the resource to be imported relative to the current location—that is, the location where the import statement is. There are two types of relative imports: implicit and explicit.

How does relative import work in Python?

Relative imports use dot(.) notation to specify a location. A single dot specifies that the module is in the current directory, two dots indicate that the module is in its parent directory of the current location and three dots indicate that it is in the grandparent directory and so on.

What is __ init __ PY for?

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.

Can not import name Python?

The Python "ImportError: cannot import name" occurs when we have circular imports (importing members between the same files). To solve the error, move the objects to a third file and import them from a central location in other files, or nest one of the imports in a function.


2 Answers

I realize this is an old question, but I feel the accepted answer likely misses the main issue with the questioner's code. It's not wrong, strictly speaking, but it gives a suggestion that only coincidentally happens to work around the real issue.

That real issue is that the foobar.py file in top\foo\bar is being run as a script. When a (correct!) relative import is attempted, it fails because the Python interpreter doesn't understand the package structure.

The best fix for this is to run foobar.py not by filename, but instead to use the -m flag to the interpreter to tell it to run the top.foo.bar.foobar module. This way Python will know the main module it's loading is in a package, and it will know exactly where the relative import is referring.

like image 198
Blckknght Avatar answered Sep 18 '22 07:09

Blckknght


You must import foobar from the parent folder of top:

import top.foo.bar.foobar

This tells Python that top is the top level package. Relative imports are possible only inside a package.

like image 35
Janne Karila Avatar answered Sep 19 '22 07:09

Janne Karila