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.
Related
I've added one folder into my project called folderb as follows:
mainproject
foldera
__init__.py (empty)
filea.py (module)
folderb
__init__.py (empty)
fileb.py (module)
My project is located under:
/root/Documents/Repositories/mainproject/
Inside filea.py module i want to use module's functions of fileb.py from folderb therefore i import as follows:
from folderb.fileb import myfunctionb
Nevertheless i am getting this:
Exception has occurred: ModuleNotFoundError
No module named 'folderb'
What am i doing wrong?
The issue is set up of sys.path with two different way of execution of the script. Go to mainproject folder. This would work:
python -m foldera.filea
and this would not
python foldera/filea.py
You can see why it is so by adding this to beginning of foldera/filea.py before any other import:
import sys
print(sys.path)
Invocation using the path will add /root/Documents/Repositories/mainproject/foldera to the path where Python interpreter looks for modules. Invocation using the package and module name (with -m option) would add /root/Documents/Repositories/mainproject/.
You can make the path variant working by augmenting the sys.path, either with
PYTHONPATH=. python foldera/filea.py
or by adding this ugly code to the beginning of filea.py:
current = os.path.dirname(os.path.realpath(__file__))
parent = os.path.dirname(current)
sys.path.insert(0, parent)
Don't do that, use the first option. More information:
PEP 338 – Executing modules as scripts
Python documentation - Command line and environment, option -m
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
I wanted to import a file from another folder into another file in the same root folder.
Directory list:
ROOT/
resource/
console_log/
__init__.py (empty)
file1.py
libs/
__init.py__ (empty)
function.py
__init__.py (empty)
I tried using this code in resource/console_log/file1.py:
from resource.libs.function import function_name
It just doesn't work. Returns this error:
No module named 'resource'
If I use this code instead
from ..libs.function import function_name
It gives me this:
attempted relative import with no known parent package
How can I solve?
Is there any way to fix it without using the sys?
EDIT:
I "fixed" the problem by moving all the files directly to the libs folder thus removing the resource folder. Except that if from libs/file1.py I want to import a function present in the main.py file I get the same error
New folder structure:
ROOT/
libs/
__init__.py
file1.py
file2.py
function.py
logs/
debug.log
__init__.py
main.py
If I use this code in the libs/file1.py file, it works correctly (only if I start it from the main.py file)
# file1.py
from libs.function import function_name
But if in libs/file2.py I want to recall a variable present in the main.py file, it returns me an error
# file2.py
from main import data
# ERROR
No module named 'main'
If he doesn't give me this error he gives me another one
attempted relative import with no known parent package
I think your PYTHONPATH isn't set correctly. You can either export it or run your program with it set as expected for the single command. The following will set the PYTHONPATH for the single command execution:
PYTHONPATH=./:$PYTHONPATH python resource/console_log/file1.py
I'm on Windows 10, using Python 3.8.3. Here is my simple folder structure:
root_project_folder\
__init__.py # Empty file
project_1_folder\
__init__.py # Empty file
foo.py
project_2_folder\
__init__.py # Empty file
bar.py
Within foo.py I have the following code:
from ..project_2_folder.bar import Test
Test.test_method()
Within bar.py I have the following code:
class Test:
#staticmethod
def test_method():
print("Test successful")
When I run foo.py, I receive the following error:
ImportError: attempted relative import with no known parent package
I've read a few threads about importing using relative paths. Here are the threads for reference:
Python3 relative imports failing in package
Importing files from different folder
What is init.py for?
I did not append any directories to sys.path. I also did not modify PYTHONPATH either, such as adding directories as an environment variable. From what I have read, I don't need to do any of that. Would I have to add something to one of the __init__.py files?
Any help would be appreciated.
common/src/validation/file1.py
In the common/src/validation/ and common/src/ folder "_init_" is defined.
common/test/validation/file2.py
common/test/validation/case/file3.py
In file2.py and file3.py, I want to import class from file1.py.
Im giving the following line in file2.py and file3.py.:
from file1 import class1
I currently get error:
#ImportError: No module named file1
what should be the sys.path.append ?
If you want to import a file from a folder you should have a file named
__init__.py
in that folder (it could also be a blank file).
You can basically just change PYTHONPATH to common and run from there. Then reference all import paths in relation to that.
like so: (assuming you are in common and your main is in file3.py)
PYTHONPATH=. python test/validation/case/file3.py
Make sure to have __init__.py files in any directory you import (the content of this file doesn't matter)
I usually like putting in the root of every project a run.sh file with some version of this line (pointing to wherever my main func is) in it.
It will usually contain a simple something like that:
#!/bin/bash
source some_env/bin/activate # start the relevant environment if you have one
PYTHONPATH=. python src/main.py # set PYTHONPATH and run
deactivate # exit the relevant environment if started one
Another option is to do this but is't not as elegant.