You seem to be adding path to mysite package, not Project1. But app1 is located in Project1, so Python can't find it.
Try this:
sys.path.append("/home/jack/workspace/Project1")
Answer from ovgolovin on Stack OverflowYou seem to be adding path to mysite package, not Project1. But app1 is located in Project1, so Python can't find it.
Try this:
sys.path.append("/home/jack/workspace/Project1")
From your drawing, app1 is a sibling to mysite—that is, it's in /home/jack/workspace/Project1/app1/, not /home/jack/workspace/Project1/mysite/app1/.
So, sys.path.append("/home/jack/workspace/Project1/mysite") isn't going to do you any good; you need `sys.path.append("/home/jack/workspace/Project1/")'.
I am not sure if maybe there is a problem because the name of the module is Module. However when I append it and I print the sys.path.append(). I see the file. When I append the path am I appending the actual file or the folder. I did both and they are still not working.
File where I want to export : \Refresh\Personal_Projects\PCEP\PCEP_pt2\Module\main1.py
Current File I'm in :\Refresh\Personal_Projects\PCEP\PCEP_pt2\Module\mod4.py
import sys
sys.path.append('D:\Refresh\Personal_Projects\PCEP\PCEP_pt2\Module')
from Module import main1
info = 'txt'
writeto(info) # writeto is the function within main1
ModuleNotFoundError: No module named 'Module'
2 errors in your code:
- The
Projectdirectory is not just 1-level up. From the point of view offile1.py, it is actually 2 levels up. See this:
$ cd ..
(venv) nponcian 1$ tree
.
└── Project
├── folder1
│ └── file1.py
└── folder2
└── file2.py
(venv) nponcian 1$ cd Project/folder1/
(venv) nponcian folder1$ ls ..
folder1 folder2
(venv) nponcian folder1$ ls ../..
Project
- Even if the above works, adding a relative path as a string would literally append that string as its raw value. So if you add a
print(sys.path), it would display something like this:
['/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '../Project', '.']
- It literally added
'../Project', so if python started searching for the target modules in folder2, it wouldn't still find them because how would it know where exactly is'../Project'relative to.
Solution
What you need to add is the absolute path. If your problem is it might change, it is fine because we don't need a fixed absolute path. We can get the absolute path through the location of the current file being executed e.g. file1.py and then extracting the parent directory needed. Thus, this will work regardless if the absolute paths change because the way we are getting it is always relative to file1.py. Try this:
Project/folder1/file1.py
from pathlib import Path
import sys
sys.path.append(str(Path(__file__).parent.parent.parent)) # 1. <.parent> contains this file1.py 2. <.parent.parent> contains folder1 3. <.parent.parent.parent> contains Project
... the rest of the file
TL;DR
You can solve this by creating a setup.py file for your project and then running pip install -e ., instead of modifying sys.path.
Motivation
This answer might seem to come from left field for this question, but I'm putting it here because OP showed interest in this solution, and I think it's generally a preferable solution to mucking around with sys.path.
Details
The solution I tend to prefer for my projects is to create an actual setup.py for them, as if I was going to publish them to PyPI, and then run pip install -e . to have them actually installed in my (possibly virtual) python environment.
Here's a minimalist setup.py similar to one I used before:
from setuptools import setup
setup(
name="project",
version="0.0.1",
python_requires=">=3.6",
author="Some cool dude",
long_description="Some cool project",
install_requires=["dep1", "dep2"],
)
In another project, I read my requirements.txt file in my setup.py:
from setuptools import setup
with open("requirements.txt") as f:
requirements = f.read().splitlines()
setup(
name="project",
version="0.0.1",
python_requires=">=3.6",
author="Some cool dude",
long_description="Some cool project",
install_requires=requirements,
)
With either solution, the setup.py file is sibling to my project directory (I use lowercase for my project names, always), both typically being at the root of my Git repo, or under a src subdirectory.
cd to the directory where setyp.py and project are, and run
pip install -e .
and now from anywhere, you can import project or its submodules and Python will find them.
Suggested reading
Lots more details can be found about setup.py files at setup.py examples?
How is this possible when the path is definitely correct
sys.path.insert(0, '/pyproj/ports/port_checker/port_checker.py')
from port_checker import get_free_port
Traceback (most recent call last):
File "check_followers.py", line 34, in <module>
from port_checker import get_free_port
ImportError: No module named port_checkerSo I am trying to run a python script. I used the following code
import.sys
sys.path.append ("C:\ABC\ABC\Repository\Final")
The file I'm trying to import is called "results.py" and is in the "Final" folder. However, every time I type in "results.py" in the next line, I get an error message saying the file can't be found. Am I getting the syntax wrong?
I am trying to run the module from my desktop and I tried to use sys.path. append to append the path to the list. But it throws an error.
C:\Users\KrishnamurthyKA\PycharmProjects\Strings\venv\Scripts\python.exe C:/Users/KrishnamurthyKA/.PyCharmCE2019.2/config/scratches/scratch.py
Traceback (most recent call last):
File "C:/Users/KrishnamurthyKA/.PyCharmCE2019.2/config/scratches/scratch.py", line 5, in <module>
import my_module as mm
ModuleNotFoundError: No module named 'my_module'
Process finished with exit code 1
Code:
import sys sys.path.append(r"C:\Users\KrishnamurthyKA\Desktop\my_module") import my_module as mm courses = ['History','Math','Physics','CompSci'] index = mm.find_index(courses, 'Math') print(index) print(test) print(sys.path)
The general answer to this question should be don't, I guess. Messing with relative paths means that the path is relative to the place from where you're calling it. That's why PYTHONPATH is worth embracing instead.
Let's assume, your directory structure looks like this:
./projects/myproject/ElementExtractor.py
./projects/myproject/test/ElementExtractorTest.py
Now, you're calling your script like this:
[./projects/myproject]$ python3.5 ./test/ElementExtractorTest.py
Your current directory is myproject and in ElementExtractorTest.py you're adding ../ directory to sys.path. This means, that ./projects/myproject/../ (i.e.: ./projects) is effectively added to your PYTHONPATH. That' why Python is unable to locate your module.
Your code would work from test directory though:
[./projects/myproject/test]$ python3.5 ./ElementExtractorTest.py
Now, by adding .. to sys.path you are effectively adding ./projects/myproject/test/../ (i.e. ./projects/myproject) to sys.path, so the module can be found and imported.
my folder structure
./test.py
./Data.py
from test.py
import Data
obj = Data.Myclass()
update
in your case
from ..ElementExtractor import MyClass
Hope this helps :)
How python finds its modules
Strictly taken, a module is a single python file, while a package is a folder containing python files, accompanied by a (can be empty) file named __init__.py, to tell python it is a package to import modules from. In both cases, modules need their .py extension, but importing them is done without (see further below).
By default, Python looks for its modules and packages in $PYTHONPATH.
To find out what is included in $PYTHONPATH, run the following code in python (3):
import sys
print(sys.path)
How to add a directory
Occasionally
From within a python file, you can add path(s) occasionally to the default path by adding the following lines in the head section of your python application or script:
import sys
sys.path.insert(0, "/path/to/your/package_or_module")
For example:
if I have a folder: /home/myname/pythonfiles, and I want to import the file module_1.py, located in that directory, I add this to the head section of my code:
import sys
sys.path.insert(0, "/home/myname/pythonfiles")
And I can simply import the file module_1.py by:
import module_1
When I create a package and want to import module(s) from the package, I need to create a folder in $PYTHONPATH, containing the modules, accompanied by a (can be empty) file called __init__.py
For example:
To import from a package (folder) called my_package in /home/myname/pythonfiles , add the /home/myname/pythonfiles path to your $PYTHONPATH, like in example 1, and import the module called module_2.py (inside the package folder) simply with: `
from <packagename> import module_2
Adding directories to $PYTHONPATH permanently:
Add the following line to your ~/.profile file.
export PYTHONPATH=$PYTHONPATH:/path/you/want/to/add
Subdirectories
From within a package, subdirectories are not included just like that; you need to "chain" the directories. To import a module module_3.py, inside folder subfolder inside folder packagename:
import packagename.subfolder.module_3
Given the fact that all subfolders in the package include their own __init__.py file.
When a module is in the same directory as the script or application
There is no need to insert the path to a module when it is in the same directory as the script or application, it is automatically added.
Example:
If I have a folder, containing script.py and module.py, I can simply import the module by:
import module
The correct way to use relative import is:
from ..Common import foo1
And you also need a __init__.py in all your folders.
I'm afraid you can't do it that way.
Because of structure:
/home/sam/pythonModules/module1/lib/module1.py
/home/sam/pythonModules/module2/lib/module2.py
You can't put both:
/home/sam/pythonModules/module1and/home/sam/pythonModules/module2
in sys.path and expect that Python will find:
module1inmodule1/libandmodule2inmodule2/lib
when you try import like:
from lib.module1 import A
from lib.module2 import B
If you put /home/sam/pythonModules/module1 before /home/sam/pythonModules/module2 in sys.path array, then import lib.MODULE will search for MODULE in /home/sam/pythonModules/module1/lib.
Since there is only module1 and no module2 in it, you get error.
What you can do is to put both
/home/sam/pythonModules/module1/lib/and/home/sam/pythonModules/module2/lib/
in sys.path and expect Python to correctly import them with next lines:
from module1 import A
from module2 import B
Useless to use sys.path.insert, only if you want to prioritize your project before another in PYTHONPATH.
import sys
sys.path.append("/home/sam/pythonModules/module1")
sys.path.append("/home/sam/pythonModules/module2")
from lib.module1 import A
from lib.module2 import B
Your projects module1 / module2 should be also structured as valid package, let see official guidelines: http://docs.python-guide.org/en/latest/writing/structure/
You need to make sure that you've altered your sys.path before you attempt to load any package that might depend on the altered path - otherwise your script will fail the moment it encounters and import statement. In other words, make sure your Main.py begins as:
import os
import sys
path = os.path.join(os.path.dirname(__file__), os.pardir)
sys.path.append(path)
from dirA.ClassA import ClassA
To ensure that the last import statement operates on the altered path.
Thanks for all the help. Per suggestion, I added the appended path as the first statement. That still didn't work. But then I used:
sys.path.append(sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
And this suddenly worked. Still not sure why the abspath makes a difference as the printed path I got was already absolute for __file__.
Perhaps I'm missing something, but this file path...
C:\Netra_Step_2015\Tests\SVTestcases\Common\shared
...isn't in your sys.path, so it's not surprising you got an error. You have several options though. Changing your project structure or, if Common and shared are actual packages with __init__.py defined inside of them, do:
import Common.shared.testCaseBase
You can also just append the path in your calling script, so:
sys.path.append('\SVTestcases\Common\shared')
Or, actually just add the following path to your ENV variable (PYTHONPATH)
C:\Netra_Step_2015\Tests\SVTestcases\Common\shared
But it's not necessarily a good habit to substitute good directory structure and importing techniques with editing your PYTHONPATH each time. You'll be much better off if you resolve this another way.
put
C:\Netra_Step_2015\Tests\SVTestcases\Common\shared
in your PYTHONPATH env