BugSquanch
BugSquanch

Reputation: 326

Python: accessing __init__.py function from within package

I am trying to find a way to define a log function inside the widgets/__init__.py file which I can then use in the subpackages.

Currently I have this filestructure:

app.py
widgets/__init__.py
widgets/input/__init__.py
widgets/input/input.py

Contents of app.py:

import widgets

widgets.input.create_foo()

Contents of widgets/__init__.py:

from .input import input

def foo():
    print('foo')

Contents of widgets/input/input.py:

from .. import foo

def create_foo():
    foo()

If I run it like this I get the error 'ImportError: cannot import name 'foo' from 'widgets' from widgets/__init__.py. Which makes total sense because I try to import a function that is not created yet.

I would like to avoid creating a separate module or sub-package for just this 1 function. Is there a clean way to define the 'foo()' function inside of widgets/__init__.py that can be used in sub-packages? What am I doing wrong here?

The reason why I want to do it like this is because I want to have a log function that I can use everywhere in the sub-packages without having to recreate it in every sub-package.

I'm still very new to the whole package thing so please don't roast me to hard :)

Upvotes: 0

Views: 273

Answers (1)

RafalS
RafalS

Reputation: 6334

__init__.py is not necessary. From python 3.3 every python file is a namespace package. Also, relative imports might be tricky. I suggest absolute imports approach:

.
├── app.py
└── widgets
    ├── input
    │   ├── input.py
    │   └── __pycache__
    ├── __pycache__
    └── utils.py

app.py:

from widgets.input.input import create_foo

create_foo()

input.py:

from widgets.utils import foo

def create_foo():
    foo()

Upvotes: 1

Related Questions