Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import from the __init__.py in the same directory?

Tags:

Suppose I have a module rules with the following structure:

rules ├── conditions.py ├── __init__.py 

In the script conditions.py, I'd like to import a class called RuleParserError defined in __init__.py. However, I haven't been able to figure out how to do this. (Following Python: How to import from an __init__.py file? I've tried

from . import RuleParserError 

but this leads to an ImportError: cannot import name RuleParserError when trying to run conditions.py as __main__).

like image 804
Kurt Peek Avatar asked Mar 17 '17 15:03

Kurt Peek


People also ask

Can import Python file from same directory?

Python use a variable called PYTHPATH to search modules. If a directory is not in the PYTHONPATH and isn't current directory(or sub directory) of the input script,you cann't import files in this folder. So, if we want to import a file in the different folder, we should add the folder to the PYTHONPATH first.

How do I import a file from one directory to another in Python?

We can use sys. path to add the path of the new different folder (the folder from where we want to import the modules) to the system path so that Python can also look for the module in that directory if it doesn't find the module in its current directory.

What does adding __ init __ py do?

In addition to labeling a directory as a Python package and defining __all__ , __init__.py allows you to define any variable at the package level. Doing so is often convenient if a package defines something that will be imported frequently, in an API-like fashion.

What is an __ init __ py file?

path looking for the package subdirectory. The __init__.py files are required to make Python treat directories containing the file as packages. This prevents directories with a common name, such as string , unintentionally hiding valid modules that occur later on the module search path.


2 Answers

I see 'import from parent module' as an anti-pattern in Python. Imports should be the other way around. Importing from modules's __init__.py is especially problematic. As you noticed, importing module foo.bar from foo/bar.py involves importing foo/__init__.py first, and you may end up with a circular dependency. Adding a print("Importing", __name__) to your init files helps see the sequence and understand the problem.

I'd suggest that you moved the code you want to import in conditions.py from __init__.py to a separate lower-level module, and just import some names from that module in __init__.py to expose it at higher level.

Let's suppose that you had some class Bar in your __init__.py. I'd reorganize it the following way.

__init__.py:

from bar import Bar  # exposed at the higher level, as it used to be. 

bar.py:

class Bar(object): ... 

conditions.py:

from . import Bar  # Now it works. 

Ideally an __init__.py should contain nothing but imports from lower-level modules, or nothing at all.

like image 156
9000 Avatar answered Oct 18 '22 10:10

9000


If you get

ImportError: attempted relative import with no known parent package

when you do like

import . from something 

especially from the script executed, just try

from __init__ import something 

Even though it could be problematic when there are many __init__.pys in sys.path, it would be helpful in some simple situaions.

like image 39
ghchoi Avatar answered Oct 18 '22 09:10

ghchoi