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)