Accessing the function specified in init.py
When initializing a package in Python 2.7, I need to define functions that should be common to all modules of a given package. I defined them in __init__.py
. How can I access it now inside the package? From the outside it turns out like this:
import package.module
package.foo() #обращение
Inside the package (for example, in the module module
), not defined foo
, dir(__package__)
- it also does not output this function.
Project structure:
package\ # пакет
__init__.py # здесь функция
module.py # здесь мне функцию нужно вызвать
The names are naturally different.
3 answers
Fixed
In fact, the file __init__.py is not intended for storing implementations of package-wide functions. They are suggested to be moved to other files.
Here's what the documentation says:
<...> In the simplest case, __init__.py can just be an empty file, but it can also execute initialization code for the package or set the
__all__
variable, described later.
Quote from python-guide.org:
<...> special behavior for the __init__.py file, which is used to gather all package-wide definitions.
<...>
Leaving an init.py file empty is considered normal and even a good practice, if the package’s modules and sub-packages do not need to share any code.
Lastly, a convenient syntax is available for importing deeply nested packages: import very.deep.module as mod. This allows you to use mod in place of the verbose repetition of very.deep.module.
Thus, __init__.py is needed to configure the package implementation view for the scripts that use it. For example, you can use the __all__
variable to control visible submodules, or import a class to the module level.
So the answer to your question is that now you have incorrectly distributed the implementation of functions across files, and it is worth creating a separate file with the implementation of the functions you need, rather than storing them in __init__.py.
For example, if you currently have the function boo
in the file __init__.py, you can export it to a file module.py, if necessary, by bringing it to the package level, adding the following line to your file __init__.py:
# файл package/__init__.py
from module import boo
And for external code that imports your module, it will be available not only through direct import
# файл my_script.py
from package.module import boo
But also through importing from Package size:
# файл my_script.py
from package import boo # та же функция
Sources:
Inside the package, modules are accessed via a dot when importing from other modules. If, for example, in __init__.py there is a function create_app
, then in another module lying in this same folder, importing this function will be like this:
from . import create_app
And if the module is in a sub-folder, then after two points:
from .. import create_app
More detailed information can be found either in the official documentation on docs.python.org, or in the book "Python. Detailed reference guide. 4th edition of " David Beazley with ISBN 978-5-93286-157-8, starting from page 189
Starting with python3.3+
, __init__.py
not required:
It used to be a required part of a package old, pre-3.3 "regular package", not newer 3.3+ "namespace package"
If you want to include a particular module in a package, then you need to specify it in the package list like this, in setup.py
:
setuptools.setup(
name='mypackage',
version='0.0.0',
packages=['mypackage', 'mypackage.x'],
package_data={
'mypackage': ['data/hello.txt', '__x/*'],
},
)
You can also include data in a package using package_data
. If you want to include a directory, specify *
. I didn't see any fundamental difference between package_data
and packages
, except that package_data
can include both data and files *.py
.