39
votes

I have this structure of files (directory and after arrow files):

model -> py_file.py 
report -> other_py_file.py

main __init__.py:

import model
import report

model directory:

import py_file

report directory:

import other_py_file

now in other_py_file I want to import py_file, but what ever I try I give error that there is no such module.

I tried this: from model import py_file

Then: import py_file

Looks like these two folders don't see each other. What is the way to import file from other directory? Do I need to specify some additional imports in init.py files?

2
You can't import backwards in a folder structure, your structure is intended to be used from the root and do import report which will import other_py_file.. Doing import ../model will not work. - Torxed
@Torxed Found the way using link provided by you. Which was I needed to use import from app folder name like: from my_app.model import py_file. I tried something similar like from addons.my_app.model import py_file. When that didn't work, I thought I needed to do something else and skipped the part importing just from app directory. - Andrius
Check my solution below instead.. it fits your model of programming better i think. - Torxed
@Torxed I think better solution is to just use specific path as in one of the answers provided in your link, because mainly I don't need to import many files in a way I needed now. - Andrius
My answer uses specific (absolute) paths, and can be combined with os.walk() for instance if you want to import stuff dynamicly, or just create a def superimport(name, path): and call that for each module you want to import. Just a thought. - Torxed

2 Answers

69
votes

You can add to the system-path at runtime:

import sys
sys.path.insert(0, 'path/to/your/py_file')

import py_file

This is by far the easiest way to do it.

21
votes

Python3:

import importlib.machinery

loader = importlib.machinery.SourceFileLoader('report', '/full/path/report/other_py_file.py')
handle = loader.load_module('report')

handle.mainFunction(parameter)

This method can be used to import whichever way you want in a folder structure (backwards, forwards doesn't really matter, i use absolute paths just to be sure).

There's also the more normal way of importing a python module in Python3,

import importlib
module = importlib.load_module('folder.filename')
module.function()

Kudos to Sebastian for spplying a similar answer for Python2:

import imp

foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()