What is the purpose of importing a package alone?

Hello all,

I’d like to know what the purpose is of importing a package alone as opposed to explicitly importing a whole module or even a resource contained within a module.

This answer on stack exchange suggests that when one imports a package alone, and that packages __init__.py does not contain any statements explicitly importing any of it’s modules or sub-packages, then there will be nothing mapped to any of the modules or sub-packages in the programs name-space.

My understanding is that in this scenario, all that has occurred is that the interpreter has searched in both the directory containing the program currently being executed and, failing that, the elements of sys.path in a specific order, until it finds either a .py file or a directory of the given name.

Assuming it finds a directory with the same name of the given package, the package name is mapped to the location of the directory (which is itself the package) and the file init.py within the directory is parsed.

Is it the case that if init.py is empty, this mapping is essentially useless without executing a further statement explicitly importing either a module, or a sub-package with an init.py file that actually contains something meaningful / useful - i.e an import statement naming a module / modules or a resource / resources within a module?

This is a fairly normal thing to do. For example import logging is the most common way to import the standard library’s logging module. Doing so allows you to refer to many functions and constants from that package (and keep in mind that a ‘package’ is also a ‘module’).

I just added import importlib.resources in a project I’m working on, so that I can then refer to importlib.resources.read_text() in the code where I need it.

Thank you for your answer. Just to clarify, I understand the mechanics of importing modules and / or their contents, my question was more: is there a practical application for importing a package (i.e a directory containing modules / sub-packages) that does not automatically import any of it’s contents via the __init__.py file.

Or, is this something that is syntactically legal but would require further steps (such as an additional, explicit import statement naming a specific element of the package) to be of any use?

It maybe does not matter so much, for small applications, but importing things, has an accumulative effect on larger applications, if a relatively large amount of external resources are being imported.

As an example, why would one want to import time, which brings in x amount of functions, just to use sleep(), when one can simply from time import sleep

To add…

It’s also better (from a readability standpoint) to be explicit with imports, so that one can see what is being used, simply from the import statement.

1 Like

Let’s be concrete: if we have a package:

+-- __init__.py
+-- boiling.py
+-- roasting.py
+-- frying.py

then by default import cooking will only load the contents of cooking/__init__.py, not the other modules (or subpackages, if any) inside the cooking directory.

This is deliberate. It allows the package author to separate their code, so that users who need cooking.frying don’t have to load cooking.boiling and cooking.roasting as well.

So what should the package author put inside cooking/__init__.py? That is entirely up to them, and it depends entirely on the design of the package. The author could include generic cooking functions, or expose selected functions from some or all of the other modules, whatever design makes sense for the package.

Or they could leave it entirly empty, in which case import cooking is legal but not very useful.

If the __init__.py file is empty, then the author’s intent is probably that users will import the submodules, not cooking itself:

import cooking.frying

But of course it is perfectly legal for users to import cooking. They just won’t be able to do much with it.

Is there a practical application for such a thing? I don’t think it is so much that people deliberately design their package to have an empty init file for some practical reason, and more the absense of any practical reason to have a non-empty init file.

The init file is needed for it to be a package. (Namespace packages excepted, but they’re a somewhat more advanced feature.) So the package gets an init file. Doesn’t necessarily mean that there is anything useful that should go in it.