People have pointed out the sys.path.append("..")
route. While this works there is also an alternative method with os.chdir('..')
You can view a list of your path with the following command python3 -m site
. When importing packages Python checks for modules in all of those paths.
The first element in your sys.path
is the current working directory.
There may be a scenario where you don't want to have your current working directory be part of the path and want to have one folder structure up added to path.
An "issue" is there are multiple ways of importing the same thing. For instance you have:
project/
├── important.py
└── files
├── file1.py
└── file2.py
By doing sys.path.append("..")
and running the program via python3 file1.py
you can import file2 via import file2
or from files import file2
. This doesn't look nice and you might start write inconsistent code while not understanding how import properly works.
You can stick with sys.path.append("..")
if it works. You won't do much wrong with it. It is a common approach many people do. There may just be a special scenario where you might run into problems which is why many people prefer the os.chdir()
approach.
For example in both folder, top folder and subfolder, you have python modules which share the same name. You want to import Python modules from one folder up but not the python modules in the current folder.
Example of os.chdir()
in action:
Tin@ubuntu:~/Desktop/tmp/test$ python3
Python 3.6.8 (default, Oct 7 2019, 12:59:55)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.getcwd()
'/home/Tin/Desktop/tmp/test'
>>> import helloworld
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'helloworld'
>>> os.chdir('..')
>>> import helloworld
hello world!
>>> os.getcwd()
'/home/Tin/Desktop/tmp'
Now you can import from one directory up and the import is no longer ambiguous.
Note that while I wrote os.chdir('..')
you can do what @Tawy did.
import os
os.chdir(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
# OR:
os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))
It looks confusing but with this you can internally imagine what your current working directory is and base all your import statements on that. It also gives you a consistent current working directory when you are executing your script from all sorts of subdirectories but expect a certain working directory.
You may also do the mistake of running os.chdir('..')
twice which will make you go two folders structure up.
In short:
Least complicated solution is sys.path.append("..")
. A cleaner solution would be os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))
with the ..
being the relative location to your wanted working directory.