I posted a similar answer also to the question regarding imports from sibling packages. You can see it here.
Solution without sys.path
hacks
Summary
- Wrap the code into one folder [e.g.
packaged_stuff
] - Create a
setup.py
script where you use setuptools.setup[]. - Pip install the
package in editable state with
pip install -e
- Import using
from packaged_stuff.modulename import function_name
Setup
I assume the same folder structure as in the question
.
└── ptdraft
├── __init__.py
├── nib.py
└── simulations
├── __init__.py
└── life
├── __init__.py
└── life.py
I call the .
the root folder, and in my case it is located in C:\tmp\test_imports
.
Steps
- Add a
setup.py
to the root folder -- The contents of thesetup.py
can be simply
from setuptools import setup, find_packages
setup[name='myproject', version='1.0', packages=find_packages[]]
Basically "any" setup.py
would work. This is just a minimal working example.
- Use a virtual environment
If you are familiar with virtual environments, activate one, and skip to the next step. Usage of virtual environments are not absolutely required, but they will really help you out in the long run [when you have more than 1 project ongoing..]. The most basic steps are [run in the root folder]
- Create virtual env
python -m venv venv
- Activate virtual env
. venv/bin/activate
[Linux] or./venv/Scripts/activate
[Win]
- Deactivate virtual env
deactivate
[Linux]
To learn more about this, just Google out "python virtualenv tutorial" or similar. You probably never need any other commands than creating, activating and deactivating.
Once you have made and activated a virtual environment, your console should give the name of the virtual environment in parenthesis
PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
[venv] PS C:\tmp\test_imports>
- pip install your project in editable state
Install your top level package myproject
using pip
. The
trick is to use the -e
flag when doing the install. This way it is installed in an editable state, and all the edits made to the .py files will be automatically included in the installed package.
In the root directory, run
pip install -e .
[note the dot, it stands for "current directory"]
You can also see that it is installed by using pip freeze
[venv] PS C:\tmp\test_imports> pip install -e .
Obtaining file:///C:/tmp/test_imports
Installing collected packages: myproject
Running setup.py develop for myproject
Successfully installed myproject
[venv] PS C:\tmp\test_imports> pip freeze
myproject==1.0
- Import by prepending
mainfolder
to every import
In this example, the mainfolder
would be ptdraft
.
This has the advantage that you will not run into name collisions with other module names [from python standard library or 3rd party modules].
Example Usage
nib.py
def function_from_nib[]:
print['I am the return value from function_from_nib!']
life.py
from ptdraft.nib import function_from_nib
if __name__ == '__main__':
function_from_nib[]
Running life.py
[venv] PS C:\tmp\test_imports> python .\ptdraft\simulations\life\life.py
I am the return value from function_from_nib!
In this article, we will learn how to Import a module from the parent directory. From Python 3.3, referencing or importing a module in the parent directory is not allowed, From the below example you can clearly understand this.
In the parent directory, we have a subdirectory, geeks.py file and in the subdirectory, we have a python file named temp.py, Now let’s try if we can import the geeks module in the parent directory from the temp.py file in the subdirectory.
geeks.py [module in the parent directory]
Python3
def
geek_method[]:
print
[
"This method in geeks module.......bye"
]
temp.py [python file in subdirectory]
Python3
from
parentdirectory
import
geeks
geeks.geek_method[]
As we have discussed earlier it is not possible to import a module from the parent directory, so this leads to an error something like this.
Traceback [most recent call last]:
File “C:/Users/sai mohan pulamolu/Desktop/parentdirectory/subdirectory/temp.py”, line 2, in
from parentdirectory import geeks
ModuleNotFoundError: No module named ‘parentdirectory’
Now let’s learn how to import a module from the parent directory:
In order to import a module, the directory having that module must be present on PYTHONPATH. It is an environment variable that contains the list of packages that will be loaded by Python. The list of packages presents in PYTHONPATH is also present in sys.path, so will add the parent directory path to the sys.path.
For our work, we use three different approaches that are explained below with the help of examples.
Method 1: Import from parent directory using sys.path method
Here we will use the sys module and set the path directly to the required module.
Add the parent directory to the sys.path using the append[] method. It is a built-in function of the sys module that can be used with a path variable to add a specific path for interpreters to search. The following example shows how this can be done.
Python3
import
sys
sys.path.append[
'../parentdirectory'
]
from
parentdirectory.geeks
import
geek_method
geek_method[]
Output:
This method in geeks module.......bye
Method 2: Import from parent directory using os.path.abspath[] method
Here we will use the sys module as well as the path module for getting the directory and set the path directly to the required module.
Syntax: os.path.abspath[path]
Parameter:
Path: A path-like object representing a file system path.Return Type: This method returns a normalized version of the pathname path.
Firstly we will get the name of the directory where the temp.py file is presently using the path.path[__file__].abspath[], secondly add the directory to the sys.path.append to check, we will use its method.
Python3
import
path
import
sys
directory
=
path.path[__file__].abspath[]
sys.path.append[directory.parent.parent]
from
parentdirectory.geeks
import
geek_method
geek_method[]
Output:
This method in geeks module.......bye
Method 3: Import from parent directory using os.path.dirname method
Here we will use the sys module as well as the os module for getting the directory [current as well as a parent] and set the path directly to the required module.
Syntax: os.path.dirname[path]
Parameter:
path: A path-like object representing a file system path.Return Type: This method returns a string value which represents the directory name from the specified path.
Firstly we will get the current directory by using the os.path.dirname[os.path.realpath[__file__]], secondly, we will get the parent directory by using the os.path.dirname[], finally, add the parent directory to the sys.path to check, we will use its method.
Python3
import
sys
import
os
current
=
os.path.dirname[os.path.realpath[__file__]]
parent
=
os.path.dirname[current]
sys.path.append[parent]
import
geeks
geeks.geek_method[]
Output: