Python modules: Difference between revisions
Line 109: | Line 109: | ||
|} | |} | ||
</blockquote><!-- magic modules --> | </blockquote><!-- magic modules --> | ||
= Lazy Module Attributes = | |||
<blockquote> | |||
See https://docs.python.org/3.6/reference/datamodel.html#customizing-module-attribute-access | |||
And https://stackoverflow.com/questions/1462986/lazy-module-variables-can-it-be-done | |||
<syntaxhighlight lang="python"> | |||
import sys | |||
import types | |||
class _Sneaky(types.ModuleType): | |||
@property | |||
def DOWNLOAD_FOLDER_PATH(self): | |||
if not hasattr(self, '_download_folder_path'): | |||
self._download_folder_path = '/dev/block/' | |||
return self._download_folder_path | |||
sys.modules[__name__].__class__ = _Sneaky | |||
</syntaxhighlight> | |||
</blockquote><!-- Lazy Module Attributes --> |
Latest revision as of 01:32, 14 February 2024
Sample Project
myproject/ | utils/ | |- __init__.py | |- filesystem.py | +- platform.py | |- __init__.py +- core.py
Concepts
terminology
Python code is organized into packages and modules.
- a package is a directory containing the file
__init__.py
, and optionally other modules.- a module is a python file
yourfile.py
$PYTHONPATH
Importing a package/module means adding all of the variables/functions/classes from that file into the current file.
A module or package can be imported once it is added to the environment variable
$PYTHONPATH
. The$PYTHONPATH
is similar to the$PATH
variable, it can contain multiple directories separated by a ':' (unix) ';' (windows).If you have a package nested within another package, only the top-most package needs to be added to the path.
site-packages
This is the location that external python-packages get installed to. You can customize, alter, or add to your list of site-packages directories. See https://docs.python.org/3/library/site.html
importing code
import
When importing a package, it's
__init__.py
is treated as that package's module. Any functions, clases etc defined there will imported with the package.import module # $PYTHONPATH/module.py import package.module # $PYTHONPATH/package/module.py import package.subpkg.module # $PYTHONPATH/package/subpkg/module.pyOnce a module is imported, it can be used using the full importpath
package.subpkg.module.my_func()This is a lot of typing. Alternatively, you can use the keywords
from
oras
to change what your module is referred to as.# $PYTHONPATH/package/subpkg/module.py from package import subpkg # subpkg.function() from package.subpkg import module # module.function() import package.subpkg.module as module # module.function()NOTE:
you can import specific classes/functions from a module, but it is considered a bad practice.
It makes it difficult to discern where each item came from, makes it easier to accidentally create a name-clash, makes it more complicatedto reload a module.
NOTE:
you can import modules/packages from anywhere within your module. If you import a module within a function, you add it to only that function's namespace.
Not adding modules at the top of your file is considered a bad practice. It makes it more difficult to do refactoring, it is difficult to predict dependency-cycles, and it means more duplicate code.
importlib
You can also dynamically import items:
import importlib module = importlib.import_module( my.package.module )
magic modules
__init__.py
Marks the parent directory as a python-package. This files contents will be available from the imported package's namespace. __main__.py
If a python package (or a package.zip) is run directly, this file's contents are run. Ex: python mypackage.zip
.
Lazy Module Attributes
See https://docs.python.org/3.6/reference/datamodel.html#customizing-module-attribute-access And https://stackoverflow.com/questions/1462986/lazy-module-variables-can-it-be-done
import sys import types class _Sneaky(types.ModuleType): @property def DOWNLOAD_FOLDER_PATH(self): if not hasattr(self, '_download_folder_path'): self._download_folder_path = '/dev/block/' return self._download_folder_path sys.modules[__name__].__class__ = _Sneaky