up:: [[Python MOC]] Python gives you a number of options for exporting the public portions of your package's API depending on the needs of your users. These are exposed via `__init__.py`. This allows the developer to have a module structure that is optimized for developers while exposing an API that is optimal for the end user. Given the following example package with 3 modules: ``` /src /example_pkg __init__.py foo.py bar.py baz.py setup.py README.md LICENSE ``` And the functions from each module: ```python # foo.py def foo_func(): print(‘this is a foo function’) # bar.py def bar_func(): print(‘this is a bar function’) # baz.py def baz_func(): print(‘this is a baz function’) ``` You can take a few different approaches, each of which have their own advantages and disadvantages, which are outlined in the [[Organizing Python Packages and User-Facing API with __init__#^fkk3ws|source article]]. This serves as a quick references ## The Naive Approach By leaving `__init__.py` empty, you expose the underlying module structure to the user. This will expose all functions in all modules in the package. ```python import example_pkg example_pkg.foo.foo_func() # or from example_pkg import bar bar.bar_func() # or import example_pkg.baz as ex_baz ex_baz.baz_func() ``` You can achieve the same flexibility for limited modules by adding the modules you want to expose to `__init__.py`: ```python import example_pkg.foo import example_pkg.bar import example_pkg.baz ``` ## Make All Functions Public Under Package This enables your user to access all functions in the module(s) you make public but under the package's namespace instead of the module's within the package. `__init__.py` ```python from .foo import * from .bar import * from .baz import * ``` Calling the functions: ```python import example_pkg example_pkg.foo_func() example_pkg.bar_func() example_pkg.baz_func() ``` This has the added advantage of [hiding module functions marked private with a single underscore](https://stackoverflow.com/questions/1547145/defining-private-module-functions-in-python) due to the `import *`. ## Make Specific Functions Public Under Package This enables you to explicitly define which functions are made public by your module. This method is the least flexible for the user, but for smaller packages allows the developer to create a clean interface for users. This doesn't scale well for larger packages, however. `__init__.py` ```python from .foo import foo_func from .bar import bar_func from .baz import baz_func ``` Calling the functions: ```python import example_pkg example_pkg.foo_func() example_pkg.bar_func() example_pkg.baz_func() ``` ## Source [What's __init__ for me? by Jacob Deppen](https://towardsdatascience.com/whats-init-for-me-d70a312da583 (summarize them in a note)