> Project
>> __init__.py
>> moduleA
>>> __init__.py
>>> file_1.py
>> moduleB
>>> __init__.py
>>> file_2.py
I have the following Directory Structure for a Python Project. I want to import file_1.py into file_2.py . How can I do so ?
I tried inserting the given below snippet in file_2.py:
from ..moduleA import file_2
But I keep Getting this error:
ImportError: attempted relative import with no known parent package
I also tried this
from Project.moduleA import file_1
This method works in the PyCharmIDE but won't work in VSCode wherein I get this error
ModuleNotFoundError: No module named 'Project'
Related
I'm getting a ModuleNotFoundError while running my flask app with this dir structure:
project
| app
| __init__.py
| urls.py
| views.py
| __main__.py
In the project dir, while running python3 ., I'm getting a
File "./app/__init__.py", line 4, in <module>
import urls
ModuleNotFoundError: No module named 'urls'
The content of __init__.py is
#!/usr/bin/env python3
import logging
import flask_cors
import urls
from views import flask_app
log = logging.getLogger("werkzeug")
log.disabled = True
flask_cors.CORS(flask_app)
def run(host, port):
flask_app.run(host=host, port=port)
The code is a little big so this is the link to it.
If you want to import other files in the same directory in a __init__.py file, you need to use relative import syntax:
from . import urls
This way Python will look for urls.py alongside your __init__.py, instead of searching in sys.path.
The file structure for a module im creating goes as follows:
PIV
| __init__.py
| base.py
| core.py
| exceptions.py
.gitignore
LICENSE
requirements.txt
But whenever I run a file like core.py, I get the following error:
Traceback (most recent call last):
File "c:/Users/ghub4/OneDrive/Desktop/Python-Image-and-Video-tools/PIV/core.py", line 33, in <module>
from . import base
ImportError: attempted relative import with no known parent package
The same thing happens when I run the __init__.py file. I'm not sure on what went wrong because all of the python files are in the same folder. Can someone clarify what's the problem and explain how I should fix it?
Import code for core.py file:
from __future__ import absolute_import
import sys
import os
from PIL import Image
import io
from . import base
from . import exceptions
(The __init__.py folder has the same relative imports as in the core file but also including: from . import core)
Based upon the two links you will given below, here is what needed for the problem to solve:
Relative Imports error rectified
No module named base
You need to import the package as this
from mymodule import some_useful_method
Sometimes, we get the no module error, in this case, we can import like this
from module_name.classname import some_useful_method
I have a very simple project architecture:
project/
__init__.py
dira/
__init__.py
a.py
dirb/
__init__.py
b.py
All the __init__.py are empty.
a.py only contains a "hello" function:
def hello(): return "hello world"
I want b.py to use the hello function from a.py.
What I tried so far:
Following answers from this question, I tried:
import ..dira.a as aa
aa.hello
But when running b.py I get a syntax error on ..a.a
I also tried to manually add the project directory to sys.path and then run:
import dira.a as aa
aa.hello
But when running b.py I get:
ImportError: No module named 'a'
What should I do? Why the solution I found doesn't work?
Short answer:
import ..dira is invalid syntax and only from ..dira.a import hello works
Working configuration: b.py:
from ..dira.a import hello
print(hello())
Also, from docs:
"Note that relative imports are based on the name of the current
module. Since the name of the main module is always "main",
modules intended for use as the main module of a Python application
must always use absolute imports."
So if you do relative imports you cannot call b.py directly. Apperently, you cannot do it from project level either. (Python interpreter in project folder, call import dirb.b)
An error occurs:
ValueError: attempted relative import beyond top-level package
But calling import project.dirb.b makes proper output:
hello world
EDIT: Why import project.dirb.b can be called only outside of project module?
Let's look at the problem from interpreter's side.
You call import project.dirb.b. It runs dirb/init.py, 'current module' is project.dirb
Interpreter finds command from ..dira.a import hello
It treats double dot ..dira.a as "move one module up and go to dira and import a.hello". 'Current module' is project.dirb, so parent module is project, thus it finds parent.dira
What happens when you call import dirb.b directly? It fails on trying to go level up in module hierarchy and reports error.
Thus, relative import makes project.dirb.b importable only outside of project.
I would like to import a class from my submodule without having to use the from submodule.submodule import Class syntax. Instead I would just like to do from submodule import Class like a normal Python3 module.
I feel this should have been answered a million times, and while there are several similarly named questions on SO, none of them provide a clear, simple solution with a bare-bones example.
I'm trying to get the simplest test working with this setup:
.
├── main.py
└── test
├── __init__.py
└── test.py
In my test module, I have the following contents:
test.py
class Test:
def __init__(self):
print('hello')
__init__.py
from test import Test
__all__ = ['Test']
In the upper-level main.py I have the following:
from test import Test
Test()
When I try to run main.py I get:
ImportError: cannot import name 'Test'
I know I could replace the import statement in main.py with from test.test import Test, but my understanding was that one of the points of __init__.py was to make submodules accessible at the package level (with __all__ allowing to import all with from test import *)
According to PEP 404:
In Python 3, implicit relative imports within packages are no longer
available - only absolute imports and explicit relative imports are
supported. In addition, star imports (e.g. from x import *) are only
permitted in module level code.
If you change __init__.py to:
from test.test import Test
__all__ = ['Test']
then your code works:
$ python3 main.py
hello
But now it works only on python3 (and your original code works only on python2).
To have code that works on both lines of python, we have to use explicit relative import:
from .test import Test
__all__ = ['Test']
Code execution:
$ python2 main.py
hello
$ python3 main.py
hello
The project is in Python3:
Project
|
Mymodule
__init__.py
|
submodule1
__init__.py
some_script.py
|
submodule2
__init__.py
myclass.py -> implements MyCLass
Whenever I run a script, I start from my Project directory. I always execute from this Project location
In Mymodule.submodule1.some_script.py, I want to import MyClass inside some_script.py which is located in submodule2
Things that work in some_script.py
from ..submodule2.myclass import MyClass
from Mymodule.submodule2.myclass import MyClass
What I am trying to achieve is to avoid location based relative reference in my script file in my submodules. When ever I try to import a module It should search in the current directory, if not found, the go to sys.path.
So my solution is in my __init__.py of my submodule1
import os
import sys
sys.path.append(os.path.abspath('./Mymodule')) -> cwd will be "Project"
Now inside my some_script.py if I import
from submodule2.myclass import MyClass
This should work, because I have a sys.path entry to the root/parent module(Mymodule). I have verified this by print(sys.path) in some_script.py
This always throws an error:
ImportError: No module named 'submodule2.myclass
Why its not considering the sys.path to search for the module.
I was able to figure out the issue. In my sys.path, there was already a similarly named module(submodule2) in a different path way ahead of my current project path. So python was searching file in the first module that it encountered while searching for the module, which was in a different location
print(sys.path)
\somepath: ... : .... : ... :\myproject_path
\somepath -> has module(submodule2) with a similar name
\myproject_path -> has my module with a similar name submodule2