sibling - python relative import
Importing files from different folder (14)
First import sys
Second append the folder path
Third Make a blank file called __ init __.py in your subdirectory (this tells Python it is a module)
- __ init __.py
Fourth import the module inside the folder
from name-folder import name-module
I have the following folder structure.
and I want to import some functions from file.py in another Python file which resides in
from application.app.folder.file import func_name
and some other various attempts but so far I couldn't manage to import properly. How can I do this?
The answers here are lacking in clarity, this is tested on Python 3.6
With this folder structure:
main.py | ---- myfolder/myfile.py
myfile.py has the content:
def myfunc(): print('hello')
The import statement in
from myfolder.myfile import myfunc myfunc()
and this will print hello.
application as the root directory for your python project, create an empty
__init__.py file in
folder folders. Then in your
some_file.py make changes as follows to get the definition of func_name:
import sys sys.path.insert(0, r'/from/root/directory/application') from application.app.folder.file import func_name ## You can also use '*' wildcard to import all the functions in file.py file. func_name()
From what I know, add an
__init__.py file directly in the folder of the functions you want to import will do the job.
I was faced with the same challenge, especially when importing multiple files, this is how I managed to overcome it.
import os, sys from os.path import dirname, join, abspath sys.path.insert(0, abspath(join(dirname(__file__), '..'))) from root_folder import file_name
I'm quite special : I use Python with Windows !
I just complete information : for both Windows and Linux, both relative and absolute path work into
sys.path (I need relative paths because I use my scripts on the several PCs and under different main directories).
And when using Windows both
/ can be used as separator for file names and of course you must double
\ into Python strings,
some valid examples :
sys.path.append('c:\\tools\\mydir') sys.path.append('..\\mytools') sys.path.append('c:/tools/mydir') sys.path.append('../mytools')
(note : I think that
/ is more convenient than
\, event if it is less 'Windows-native' because it is Linux-compatible and simpler to write and copy to Windows explorer)
In Python 3.4 and later, you can import from a source file directly (link to documentation).
Here is an example. First, the file to be imported, named
def announce(): print("Imported!")
The code that imports the file above, inspired heavily by the example in the documentation:
import importlib, importlib.util, os.path def module_from_file(module_name, file_path): spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module foo = module_from_file("foo", "/path/to/foo.py") if __name__ == "__main__": print(foo) print(dir(foo)) foo.announce()
<module 'foo' from '/path/to/foo.py'> ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce'] Imported!
Note that the variable name, the module name, and the filename need not match. This code still works:
import importlib, importlib.util, os.path def module_from_file(module_name, file_path): spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module baz = module_from_file("bar", "/path/to/foo.py") if __name__ == "__main__": print(baz) print(dir(baz)) baz.announce()
<module 'bar' from '/path/to/foo.py'> ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce'] Imported!
Programmatically importing modules was introduced in Python 3.1 and gives you more control over how modules are imported. Refer to the documentation for more information.
In my case I had a class to import. My file looked like this:
# /opt/path/to/code/log_helper.py class LogHelper: # stuff here
In my main file I included the code via:
path.append("/opt/path/to/code/") from log_helper import LogHelper
So I had just right clicked on my IDE, and added a new
folder and was wondering why I wasn't able to import from it. Later I realized I have to right click and create a Python Package, and not a classic file system folder. Or a post-mortem method being adding an
__init__.py (which makes python treat the file system folder as a package) as mentioned in other answers. Adding this answer here just in case someone went this route.
This works for me on windows
# some_file.py on mainApp/app2 import sys sys.path.insert(0, sys.path+'\\app2') import some_file
Using sys.path.append with an absolute path is not ideal when moving the application to other environments. Using a relative path won't always work because the current working directory depends on how the script was invoked.
Since the application folder structure is fixed, we can use os.path to get the full path of the module we wish to import. For example, if this is the structure:
And let's say that you want to import the "mango" module. You could do the following in vanilla.py:
import sys, os.path mango_dir = (os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) + '/another_folder/') sys.path.append(mango_dir) import mango
Of course, you don't need the mango_dir variable.
To understand how this works look at this interactive session example:
>>> import os >>> mydir = '/home/me/application/app2/some_folder' >>> newdir = os.path.abspath(os.path.join(mydir, '..')) >>> newdir '/home/me/application/app2' >>> newdir = os.path.abspath(os.path.join(mydir, '..')) + '/another_folder' >>> >>> newdir '/home/me/application/app2/another_folder' >>>
And check the os.path documentation.
When modules are in parallel locations, as in the question:
This shorthand makes one module visible to the other:
import sys sys.path.append('../')
You can refresh the Python shell by pressing f5, or go to Run-> Run Module. This way you don't have to change the directory to read something from the file. Python will automatically change the directory. But if you want to work with different files from different directory in the Python Shell, then you can change the directory in sys, as Cameron said earlier.
Your problem is that Python is looking in the Python directory for this file and not finding it. You must specify that you are talking about the directory that you are in and not the Python one.
To do this you change this:
from application.app.folder.file import func_name
from .application.app.folder.file import func_name
By adding the dot you are saying look in this folder for the application folder instead of looking in the Python directory.