Is it necessary to use an init.py for a folder to be considered a package in Python 3.7?
Is it necessary to use an init.py for a folder to be considered a package in Python 3.7?
Depends on what kind of package we are talking about.
A normal package is a folder within which there are several .py
files, which are each a "module". It may even contain a subfolder that is itself a subpacket. To give an example, let's say that the contents of the folder are:
└── foo
├── a.py
├── b.py
└── c.py
As we can see, the file __init__.py
does not exist. Then, assuming that the foo
folder is inside another folder that is part of the PYTHONPATH
(that is, that python can import it), the following import
will work without problems:
import foo.a
from foo import b
import foo
None of the three will give error under python3 (although they would give it under python2 because there is no __init__.py
in the folder foo
.
import foo.a
will allow within the code to use any symbol defined in foo/a.py
, for example foo.a.MiClaseA
or whatever. from foo import b
is analogous to the previous one, but avoids having to use the prefix foo
to access the symbols of foo/b.py
, and so I can use directly b
as a namespace, for example b.MiClaseB
, etc foo/c.py
module has not been imported. I do not have access to its symbols. import foo
does not help. This order would normally execute foo/__init__.py
, but since in this case it does not exist, it does not do anything. In particular, does not automatically define subspaces a
, b
or c
. Therefore an attempt to access foo.c
will give error ( foo.a
will not give it because we import it before, foo.b
will also work because it was loaded as part of from foo import b
) Therefore, except for the detail that import foo
has not done anything, it has worked.
Now, if we add a __init__.py
, so that now the structure is:
└── foo
├── __init__.py
├── a.py
├── b.py
└── c.py
then import foo
would execute __init__.py
(this is true both in python2 and python3).
If __init__.py
is empty, which is valid, it would be exactly the same as if it were not . In python2 it was common to put a __init__.py
empty just to mark that that folder was a package. In python3 this is no longer necessary .
But we can also take advantage of and put something inside that __init__.py
. Typically this file is used to initialize certain variables or symbols that we want to be easily imported. A simple example could be:
# Contenido de foo/__init__.py
from . import a, b, c
Then, when% import foo
, since foo/__init__.py
is executed, it must also be executed foo/a.py
, foo/b.py
and foo/c.py
, and that the symbols a
, b
and c
will be defined within the foo
package, so now, from the program that made the import
, I can use foo.a
, foo.b
and foo.c
without errors.
Even if the program does from foo import a
, it will execute foo/__init__.py
and therefore the three modules it imports.
You can also do from foo import *
(although it is not recommended) and that will define the symbols a
, b
and c
(which are modules) in the namespace of who makes the import.
Another usual case within __init__.py
is to define a list called __all__
with the names of the symbols that you want to export massively. For example:
# Otro posible contenido de foo/__init__.py
from . import a, b, c
# No queremos exportar masivamente c
__all__ = ["a", "b"]
This massive export refers to another program doing from foo import *
. That asterisk will be expanded by Python to the list of symbols defined in __all__
, so in this case the program that makes that import will have access to a
and b
but not% c
. Note, however, that this is not enough to make c
"private". That concept does not exist Python. The program that does from foo import *
does not see c
, but can do from foo import c
to see it too.
Yes, the file __ init __. py is still required to initialize a package, likewise if your package has subpackets, it should also contain its own file __ init __. py , the files can be blank files.
You can get more information on your site:
Section 6.4