ImportError persists after adding the path to PYTHONPATH - python

I get the following error while running some python code
Traceback (most recent call last):
File "./dspl.py", line 4, in
import base
ImportError: No module named base
The disp.py is in directory PERSISTENCE_LENGTH, as listed below. The disp.py imports few python scripts that are inside the directory UTILS (shown below). I added the path of imported directory (/home/vinay/oxDNA) to PYTHONPATH i.e.,export PYTHONPATH=${PYTHONPATH}:/home/vinay/oxDNA/). There is a proper__init__.py file inside the UTILS directory.
disp.py is in the directory: /home/vinay/oxDNA/EXAMPLES/PERSISTENCE_LENGTH
disp.py is importing other modules that are in the directory: /home/vinay/oxDNA/UTILS
When I print sys.path, I can see that PYTHONPATH is okay. as shown below
['', '/home/vinay', '/home/vinay/oxDNA/UTILS', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', )

If your module is in a directory, rather than being a singled named file, then the directory is required to have a __init__.py file. The existence of this file makes the directory a module and then you can load from that module, the __init__.py can be empty but you can also have an entry in it of:
__all__ = ['component_name1', 'etc', 'etc']
If you do then the names listed in __all__ are those that will be available after a from mondule_name import *
The normal practice is to have a meaningful name for the directory, e.g.: `my_utils' and for the components within the directory, e.g.: 'file_io.py' and you can then access the items within file_io as:
import my_utils
my_utils.file_io.functionA()
or
from my_utils import file_io
file_io.functionA()
or
from my_utils.file_io import functionA()
functionA()
Note that in the all above examples functionA has access to other functions within file_io.py and, if file_io.py has the appropriate imports, to other functions in other files in my_utils.
It is also important to remember that python is case dependent even on windows.

Related

Python ModuleNotFoundError when executing script directly

I have browsed over a lot of questions on this topic, and I have found a lot of information, but I am still unable to fully understand what is happening and how to solve my problem
This is the question:
I am using python3.9.5, and I have the following layout:
root_folder/
src/
a.py
b.py
Inside a.py I have:
from src.b import do_something_B
def do_something_A():
do_something_B()
if __name__ == '__main__':
do_something_A()
An b.py:
def do_something_B():
print("Hello from B")
If I run Ipython REPL, I can do:
from src.a import do_something_A
do_something_A() # this prints "Hello from B" without errors
But if I try to execute a.py from console I get the following output:
❯ python src/a.py
Traceback (most recent call last):
File "/home/alejo/playground/root_folder/src/a.py", line 1, in <module>
from src.b import do_something_B
ModuleNotFoundError: No module named 'src'
Creating a __init__.py file inside src folder does not make any difference
What am I understanding wrong?
EDIT
If I change a.py to import b without src namespace (changing first line to from b import do_something_B) then I can execute the script from bash, but it fails when I try to use it with iPython REPL
You don't need to specify the directory as the two files are in the same directory already.
Simply do from b import do_something_B and it should work.
Same thing in b.py
Also to clarify, using src.someFunc implies that there is a module named src not that there is a directory named src.
Look into absolute imports if you need to import across directories, which in this case you do not, so don't worry.
I found the answer to my own question browsing the documentation:
Quoting https://docs.python.org/3/tutorial/modules.html#the-module-search-path
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
The directory containing the input script (or the current directory when no file is specified).
PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
The installation-dependent default.
As I am specifiying an script, the folder of the script is added to sys.path, not the current folder
I would need to add a c.py file directly in root_folder than imports src.a and executes do_something_A() to be able to call it from bash

ImportError: No module named utils.read

I have a main.py file in the folder project and read.py in the folder ./project/utils. In the main.py, I called
import sys, os
sys.path.append('./utils/')
from utils.read import function1
However, when I use the python main.py command, I got the error
ImportError: No module named utils.read. What should I change? Thanks all
i think you need to add __init__.py
in your directory..
make sure you have __init__.py in utils folder.. then only python will understand it is package folder contains py
__init__.py specifies that the folder is actually a package. a package in python is a directory containing .py files (modules). In every folder which is a package (that is, a folder containing multiple .py files) you should define __init__.py.
It can be empty, or you can put some statements to execute when the package is imported (or modules from the package).
For exmaple, let's take this directory tree:
/dev/package/greeter.py
and current working directory is /dev.
>>> from package import greeter
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
from package import greeter
ImportError: No module named package
import pakcage results in the same error. When adding __init__.py into the package folder, it works. My init is simple as
print 'init executed'
>>> from package import greeter
init executed
>>>
One common functionality to put in __init__.py is the __all__ variable. You can read more about it here Can someone explain __all__ in Python?

import python file in another directory failed

I met a very strange problem:
My file structure is like: (core and test are directories)
core
----file1.py
----__init__.py
test
----file2.py
in file2, i wrote:
from core import file1
result is:
ImportError: cannot import name file1
Have to create __init__.py file inside the test dir:
Because The __init__.py files are required to make Python treat the directories as containing packages.
parent/
child1/
__init__.py
file1.py
child2/
__init__.py
file2.py
From the error:
If run the child2/file2.py file directly. You are not able to access child1/file1.py from the child2/file2.py
Because only from the parent directory can access the child.
If have a folder structure like:
parent/
child1/
__init__.py
file1.py
child2/
__init__.py
file2.py
file3.py
If we run the file3.py file. Can able to access both child1/file1.py, child2/file2.py in file3.py
Because It is running from the parent directory.
If we need to access child1/file1 from child2/file2.py, We need to set the parent directory:
By running this below command we can achieve it...
PYTHONPATH=. python child2/file2.py
PYTHONPATH=. It refers the parent path. Then runs child2/file2.py file from the shell
It's not a strange problem, imports simply don't work like that.
From the official documentation: https://docs.python.org/3/tutorial/modules.html
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
The directory containing the input script (or the current directory when
no file is specified).
PYTHONPATH (a list of directory names, with the same syntax as the shell
variable PATH).
The installation-dependent default.
You could look into relative imports, here's a good source: https://stackoverflow.com/a/16985066/4886716
The relevant info from that post is that there's no good way to do it unless you add core to PYTHONPATH like Shawn. L says.
When I tried your case, I got
Traceback (most recent call last):
File "file2.py", line 3, in <module>
from core import file1
ImportError: No module named core
The reason is that Python does not find core. In this case, you need to add core to the system path, as shown below (add them at the very beginning of file2.py):
import sys,os
sys.path.append(path_to_core.py)
Or, if you would run it using command line, you could simply put the following at the beginning of file2.py
import sys,os
sys.path.append(os.path.join(os.path.dirname(__file__),'../'))
Here, os.path.join(os.path.dirname(__file__),'../') is to state the path to file2.py.

my program dont recognize beetwen modules & core i am on python2

I have a python program in which I get the following error:
ImportError: No module named core
the import causing the error is:
from core import wcolors
the file wcolors.py is inside a dir named core, there is another dir called modules, so when i run my program it give this error output:
Traceback (most recent call last):
File "anubis.py", line 7, in <module>
from core import wcolors
ImportError: No module named core
dir structure
the dir structure follows like that
anubis
--anubis.py (the script that i run)
--core
--wcolors.py (the file i import from core)
-- modules
[the modules i suposed to load during the execution.]
as another detail all files in core are compiled with .pyc extention.
You just need to add a blank __init__.py to your anubis and anubis/core directories, and this should work. If you don’t have the __init__.py file, python will not think that the directory is a module.
The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, __init__.py can just be an empty file
Python docs
You can try this:
from anubis.core import wcolors
OR you can change a name for "core", it could be a keyword for django and python.

How can I load the parent directory of a script as a module, without adding all of the siblings of that directory's parent directory to my sys.path?

I'm hoping there's an easy answer to this question that I'm simply overlooking.
Here's the setup:
foo/
__init__.py
run.py
Contents of run.py:
import foo
Run the script:
$ python run.py
Traceback (most recent call last):
File "run.py", line 1, in <module>
import foo
ImportError: No module named foo
The only way I can figure out to address this is:
Contents of run.py:
import sys
import os
path = os.path.abspath(__file__)
sys.path.append(os.path.join(os.path.dirname(path), "../"))
import foo
So that works, but the problem (if I'm not mistaken) is that this adds the parent directory of foo/ to sys.path and thus searches all of the sibling folders of foo/ for Python modules.
There's a case I have where I really, really don't want to do that. I just want to add a single directory as a module to my path, but I can't figure out how to just add that module without adding that directory's parent directory and thus every other directory beneath that parent directory.
Am I overlooking something here? Is there an easy way I can add a script's parent folder as a module?
I don't quite see why run is meant to import its own parent package. After all, a package is just meant to be a way of collecting modules together; it's not meant to have significant functionality of its own.
Packages are a way of structuring
Python’s module namespace by using
“dotted module names”. For example,
the module name A.B designates a
submodule named B in a package named
A. Just like the use of modules saves
the authors of different modules from
having to worry about each other’s
global variable names, the use of
dotted module names saves the authors
of multi-module packages like NumPy or
the Python Imaging Library from having
to worry about each other’s module
names.
Are you sure you don't want run to import a sibling module? That you can do using relative imports.

Categories