💾 Archived View for dcreager.net › languages › python › import-nested.gmi captured on 2024-12-17 at 09:33:21. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

Importing a nested module does not create a shim

You can import a nested module using the typical dot notation: ‘import os.path’. This creates a binding in the current file-global scope called ‘os’. You must access the imported nested module (and its contents) using its full path: ‘os.path.join’.

Nothing unexpected so far. But at this point, there are a few possibilities:

I can't find if it's explicitly documented anywhere, but it seems Python implements option (2): importing ‘os.path’ also implicitly imports ‘os’, but not any other submodules unless you explicitly import them.

A false start

Note that I first tried with ‘logging’—I thought it would be a better test since it contains more than one submodule.

But! This is a false positive. This behavior occurs because ‘logging.config’ itself imports ‘logging.handlers’!

Python 3.12.7 (main, Oct  1 2024, 11:15:50) [GCC 14.2.1 20240910] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import logging
>>> logging
<module 'logging' from '/usr/lib/python3.12/logging/__init__.py'>
>>> logging.config
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'logging' has no attribute 'config'
>>> import logging.config
>>> logging
<module 'logging' from '/usr/lib/python3.12/logging/__init__.py'>
>>> logging.Logger
<class 'logging.Logger'>
>>> logging.config
<module 'logging.config' from '/usr/lib/python3.12/logging/config.py'>
>>> logging.config.fileConfig
<function fileConfig at 0x71a0d3dcdda0>
>>> logging.handlers
<module 'logging.handlers' from '/usr/lib/python3.12/logging/handlers.py'>
>>> logging.handlers.WatchedFileHandler
<class 'logging.handlers.WatchedFileHandler'>

» Languages » Python