Here's my directory setup:
mydir
├── script1.py
└── shared
├── otherstuff
├── script2.py
└── pkg
├── box.py
└── __init__.py
script2.py starts with
import pkg
and it works great. When I include the same line in script1.py, I get:
Traceback (most recent call last):
File "script1.py", line 1, in <module>
import pkg
Is there any good way to get syntax that simple to work in script1.py? I have been reading about PYTHONPATH and sys.path for the past hour, but I'm trying to make some basic functions available to my repo, and I can't believe that it will require modifying PYTHONPATH everytime I want to run a script.
What am I missing here? What's the best way to get pkg into script1.py?
You have to do:
from shared import pkg
Also, your shared directory should have an __init__.py file
I tested in python 3.x , You can do either -
import shared.pkg
or
from shared import pkg
If you don't want to create the __init__.py file in shared and using import shared.pkg, you can work around this by doing:
import sys
sys.path.insert(0, 'shared')
import pkg
Related
I have this file structure
.
└── sample
├── one
│ ├── __init__.py
│ └── util.py
└── two
├── __init__.py
└── test.py
Here is the content of util.py
def isOk():
return True
Here is the content of test.py
from sample.one import util
Whenever I'm inside the [two] folder and I type
python test.py
I get
Traceback (most recent call last):
File "test.py", line 1, in <module>
from sample.one import util
ModuleNotFoundError: No module named 'sample'
How is that possible when I create all folders and __init__.py by the book?
It seems that a method to invoke it might be
python -m two.test
If one and two are both subpackages of sample, then you should add a sample/__init__.py which may be empty.
If you then invoke python -m sample.two.test from the right directory, it should work.
You could even add package-relative imports like this:
# test.py
from ..one import util
Please add the dir path to your PYTHONPATH
export PYTHONPATH=/PATH/TO/DIR/WHICH/CONTAINS/SAMPLE
2 real nice links to go through are:
https://docs.python.org/3/tutorial/modules.html
https://docs.python.org/3/reference/import.html
I have a directory structure:
root_dir
├── src
│ └── p1.py
└── lib
├── __init__.py
├── util1.py
└── util2.py
I want to run src/p1.py which uses lib/util1.py using an import statement import lib.util1 as u1.
It runs fine when I use PyCharm, but I want to also run it from command line. How can I run the program from command line?
I have tried cd root_dir then python src/p1.py.
But it produces the following error:
Traceback (most recent call last):
File "./src/p1.py", line 1, in <module>
import lib.util1 as u1
ImportError: No module named lib.util1
How can I run the python program src/p1.py from the command line?
Edit: Based on the suggestion from #Sumedh Junghare, in comments, I have added __init__.py in lib folder. But still it produces the same error!
You need the following steps
Add __init__.py at lib folder.
Add this line at p1.py file on top
import sys
sys.path.append('../')
import lib.util1 as u1
Run the p1.py file from src dir. Hope it will work.
Edit:
If you do not want to add sys.path.append('../'), set PYTHONPATH in env-var from this resource.
How to add to the pythonpath in Windows?
Improving on Saiful's answer, You can do the following which will allow you to run the your program from any working directory
import sys
import os
sys.path.append(os.path.join(os.path.realpath(os.path.dirname(__file__)), "../"))
import lib.util1 as u1
I try to understand how to split up python files belonging to the same project in different directories. If I understood it right I need to use packages as described here in the documentation.
So my structure looks like this:
.
├── A
│ ├── fileA.py
│ └── __init__.py
├── B
│ ├── fileB.py
│ └── __init__.py
└── __init__.py
with empty __init__.py files and
$ cat A/fileA.py
def funA():
print("hello from A")
$ cat B/fileB.py
from A.fileA import funA
if __name__ == "__main__":
funA()
Now I expect that when I execute B/fileB.py I get "Hello from A", but instead I get the following error:
ModuleNotFoundError: No module named 'A'
What am I doing wrong?
Your problem is the same as: Relative imports for the billionth time
TL;DR: you can't do relative imports from the file you execute since
main module is not a part of a package.
As main:
python B/fileB.py
Output:
Traceback (most recent call last):
File "p2/m2.py", line 1, in <module>
from p1.m1 import funA
ImportError: No module named p1.m1
As a module (not main):
python -m B.fileB
Output:
hello from A
One way to solve this is to add module A into the path of fileB.py by adding
import sys
sys.path.insert(0, 'absolute/path/to/A/')
to the top of fileB.py.
I'm currently writing a web application in python that needs unit tests, however whenever I try to import a child module that's in another parent directory I get the following error:
$ python my_package/tests/main.py
Traceback (most recent call last):
File "my_package/tests/test.py", line 1, in <module>
from my_package.core.main import hello
ImportError: No module named my_package.core.main
File: my_package/core/main.py
hello = "Hello"
File: my_package/test/test.py
from my_package.core.main import hello
print(hello, "world!")
My directory structure:
$ tree
.
└── my_package
├── __init__.py
├── core
│ ├── __init__.py
│ └── main.py
└── tests
├── __init__.py
└── test.py
Could someone please explain what I'm doing wrong? Thank you for your time.
It is considered an anti-pattern to modify sys.path. If you want your package to be available to all subpackages, it's better to use setup.py development mode.
Create setup.py in the root of your project:
from setuptools import setup
setup(
name="you_project",
version="0.0.0",
packages=['my_package', ],
install_requires=['requirement1', 'requirement2'],
)
Then run:
$python setup.py develop
After this you will be able to import my_packege from anywhere within your Python environment.
Your my_package is not in PYTHONPATH. At the top of your test.py add the below. Note that any change in location of test.py would affect package_path
from os.path import dirname, abspath
import sys
package_path = dirname(dirname(abspath(__file__)))
sys.path.append(package_path)
Environment: Ubuntu 14
The structure:
test
├── a
│ ├── a.py
│ └── __init__.py
├── b
│ ├── b.py
│ └── __init__.py
└── __init__.py
In "b.py":
import test.a.a
if I run "python b.py":
Traceback (most recent call last):
File "b.py", line 1, in <module>
import test.a.a
ImportError: No module named a.a
you have several options
1) Include the path to the folder test to sys.path
you can do hardcoded
b.py
import sys
sys.path.append("path/to/test")
import test.a.a
but in this case you have to change it manually if later you change the test folder to another place
you can also do automatic with
b.py
import os, sys
path = os.path.dirname( os.path.dirname( os.path.dirname(__file__) ) )
# folder_of_test/ test / b
sys.path.append(path)
import test.a.a
in this one, if you are using python 2 you need to call os.path.abspath on __file__ first
2) Add the test's parent folder to your PYTHONPATH environment variable, or put the test folder in a folder in your PYTHONPATH or PATH environment variable.
to do this do
$> export PYTHONPATH="/path/to/parent/folder/of/test:$PYTHONPATH"
but most likely will only be temporal, to do in a permanent way go to the file .profile or .bashrc in your home folder and put the above instruction in there at the end in your favorite way (I modify .profile to set my pythonpath)
3) Call your code as python -m test.b.b from the folder that contain test
in any case you have to make sure that you don't other library that have the same name, for example I have anaconda installed and that come with a test package, and in that case you should change the name to avoid confusion
The module test is part of the standard library. So when you import test.a, it tries to import the a module in it.
So, even if you find a solution, it is better you don't use that name for your package.
Try with:
from test.a import a
or with:
from ..a import a