Each Answer to this Q is separated by one/two green lines.
I am learning to program with python and I am having issues with importing from a module in a package. I am usingvisual studio code with Python 3.8.2 64 bit.
.vscode ??? ecommerce ? ??? __init__.py ? ??? database.py ? ??? products.py ? ??? payments ? ??? __init__.py ? ??? authorizenet.py ? ??? paypal.py ??? __init__.py ??? main.py
ecommerce/products.py file I have:
#products.py from .database import Database p = Database(3,2)
So that I can import the
Database class from the
ecommerce/database.py file. But I get error
ImportError : Attempted relative import with no known parent package
Since you are using Python 3.8 version, the imports work a little differently, but I think this should work:
from database import Database #Database is the class
lastly, this one is very secure and best practice possibly:
from . import Database # The '.' (dot) means from within the same directory as this __init__.py module grab the Database class.
It seems, from Python docs and experimenting, that relative imports (involving ., .. etc) only work if
- the importing module has a
__main__, and further,
__name__of the importing module is pkg.module_name, i.e., it has to be imported from above in the directory hierarchy (to have a parent pkg as part of it’s
the importing module is being specified via module syntax that includes a parent pkg as
python -m pkg.module, in which case it’s
__name__ is still
__main__, so it is being run as a script, yet relative imports will work. Here
__package__ is set and used to find the parent package while
__main__; more here.
[After all that, it appears that
sys.path are key to determining if/how relative imports work.
__name__ indicates script or module(i.e.,
__package__ indicates where in the package the relative imports occur with respect to, and the top of
__package__ needs to be in
So, continuing with @AmitTendulkar ‘s example, if you run this as
> python main.py or
> python -m main or
> python -m ecommerce.products from the project root directory, or enter interactive python from that root directory and
import main, or
import ecommerce.products the relative imports in products.py will work.
But if you
> python products.py or
> python -m products from within ecommerce directory, or enter interactive python from that ecommerce directory and
import products they will fail.
It is helpful to add
print("In module products __package__, __name__ ==", __package__, __name__)
etc. in each file to debug.
How imports work depend on
__package__, not on
> python sub/mod.py has a
None -absolute imports of modules in
sys.path work, relative imports fail.
> python -m sub.mod has
sub -absolute imports of modules in
sys.path work, relative imports work relative to
It is more helpful to add
import sys print("In module products sys.path, __package__ ==", sys.path, __package__)
etc. in each file to debug.
i had a similar issue on Windows, and what helped me was (adapted to your directory):
# local imports import sys sys.path.append(r"C:\path\to\your\project") from ecommerce.database import Database
Considering the below basic file structure
??? ecommerce ? ??? __init__.py ? ??? database.py | ??? products.py ??? main.py
I am assuming you are running
python main.py from the project root.
Here is the text copied from the Python tutorial that explains the basic rule around relative import,
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 the below code will work,
# main.py import ecommerce.products # or to use it directly # from ecommerce.products import my_product ecommerce.products.my_product()
Your product.py might look like,
# ecommerce/products.py from .database import Database def my_product(): p = Database(3, 2)
And database.py will look like below,
# ecommerce/database.py class Database(): def __init__(self, x, y): self._x = x self._y = y print('Inside DB init') # Rest of the methods...
You will now get,
> python main.py Inside DB init
__init__.py file at root is not required as the package name is starting from ecommerce.
You can also run
python -m ecommerce.products command to directly call products.py. But that won’t yield any output as we are not calling the my_product() function (only defining it).
python ecommerce/products.py will not work as the name of the current module will then become
__main__ and not
ecommerce. The relative importing only works when used within the current package (so in your main script you always need to import your
To allow the use of relative imports, you need to “turn your code into a package”. This means all of 1) putting an
__init__.py in the top directory of your code (in your example
.vscode) and 2) adding the full (absolute) path to the parent directory of the top directory (i.e., the parent of your directory
.vscode) to your
PYTHONPATH and 3) setting the
__package__ variable in your Python program to the name of the directory that contains
__init__.py, in your case “
You should then be able to use in
from .ecommerce.database import Database
I’m not sure why the dot is in the name
.vscode – is that part of the directory name, or part of the lines in your directory tree? If the latter, replace
This may seem like a hack but it actually work, this happens because of bad package structure
In you case try importing
from .vs_code.ecommerce import database
Now wherever you want to call the class constructor do this:
you can assign this to a variable and use it.
from ecommerce.database import Database
Presumably, you make executable the file “products.py”, which violates the very concept of packages, the package ceases to be a package and relative import does not work. You must call this outside the package.
Here I am also not sure whether the root directory name can start with a dot like “.vscode”.
try the following
from ecommerce import database