I have a simple example project with these files:
folder
__init__.py
foo.py
foobar.py
script.py
In foobar.py the function foo is imported with from .foo import foo.
(It is then used in the function foobar).
In script.py the function foobar is imported with from .foobar import foobar.
(It is then executed.)
But putting the dots in the import statement is not always the right choice.
Depending on how the script is run, their presence can cause:
ImportError: attempted relative import with no known parent package
Or their absence can cause:
ModuleNotFoundError: No module named 'foobar'
The code can be found on GitHub. (There is also the same with absolute paths.)
with dots
This works for the two usecases that I need:
- run script using the m-switch:
python -m project.folder.script - import
foobarin the Python console:from project.folder.foobar import foobar
This screenshot shows how running the script works with and fails without the m-switch:
without dots
Gladly there is no need to run the script without the m-switch.
(Although it would be nice, because the IDE has a button for that.)
This screenshot shows how running the script fails with and works without the m-switch:
paths in detail
It seems worthwhile to take a closer look at __name__ and __file__ in all cases.
__name__ of _script.py is always the string '__main__'.
conclusion
Apparently for me this just boils down to having to use the dot and the m-switch.
(This is just mildly annoying, because my IDE does not have auto-completion for it.)
But I would still like to understand, why there are these two ways of doing essentially the same thing.
People often say, that the dot is for going up a directory (like ../ in HTML and PHP).
But there is something wrong with that, because the location is the same in both cases.
(We just talk about neighboring files in the same folder.)
This must be far from the first question about this topic.
I hope it is clear enough to compensate for that redundancy.



Let me explain why the dot is useful and when its used.
The dot is really useful when you are creating more complex projects (like a website using Django or flask).
The simplest way to I would explain the dot in front of imports is that it basically adds the file directory into your codes import directories, let me explain.
your current directory when you are importing through
script.pyis:folder.Why without dot it works: If you don't have the dot in front of your import, you are basically telling Python to import
foo.pyfrom the same directory as yourscript.pyWhy using dot it throws an error: Because you don't use a
main.pyto run your code (the main file would be outside of your folder but in the same directory). Python considers your script.py as your__main__, This means that you cannot use the dot in imports that are in yourscript.py. This is because you haven't told Python which is the file/folder from which to import foobar.If you would have a
main.py, when importing the linefrom .foobar import foobaryou are basically writing the line:from folder.foobar import foobar. Which would be correct.Note: (This would require you to write
import folderinside yourmain.py, and writefrom . import scriptinside your__init__.py)for your code, don't use the dot in front of imports and don't use the m-switch.
I suggest that you could make a
main.pyin the same directory as yourfolder, this would make it possible for you to create a more complex script without a big headache later on. (In this case you have to add the dot in all of your code inside thefolder)