I'm taking a look at how the model system in django works and I noticed something that I don't understand.
I know that you create an empty __init__.py
file to specify that the current directory is a package. And that you can set some variable in __init__.py
so that import * works properly.
But django adds a bunch of from ... import ... statements and defines a bunch of classes in __init__.py
. Why? Doesn't this just make things look messy? Is there a reason that requires this code in __init__.py
?
So it's normally a good place to put any package-level initialisation code. The bottom line is: all names assigned in __init__.py , be it imported modules, functions or classes, are automatically available in the package namespace whenever you import the package or a module in the package.
In addition to labeling a directory as a Python package and defining __all__ , __init__.py allows you to define any variable at the package level. Doing so is often convenient if a package defines something that will be imported frequently, in an API-like fashion.
What to put in __init__.py. There is a range of options of what to put in an __init__.py file. The most minimal thing to do is to leave the __init__.py file totally empty. Moving slightly away from this, while still keeping things simple, you can use an __init__.py only for determining import order.
The __init__.py file lets the Python interpreter know that a directory contains code for a Python module. An __init__.py file can be blank. Without one, you cannot import modules from another folder into your project.
All imports in __init__.py
are made available when you import the package (directory) that contains it.
Example:
./dir/__init__.py
:
import something
./test.py
:
import dir # can now use dir.something
EDIT: forgot to mention, the code in __init__.py
runs the first time you import any module from that directory. So it's normally a good place to put any package-level initialisation code.
EDIT2: dgrant pointed out to a possible confusion in my example. In __init__.py
import something
can import any module, not necessary from the package. For example, we can replace it with import datetime
, then in our top level test.py
both of these snippets will work:
import dir print dir.datetime.datetime.now()
and
import dir.some_module_in_dir print dir.datetime.datetime.now()
The bottom line is: all names assigned in __init__.py
, be it imported modules, functions or classes, are automatically available in the package namespace whenever you import the package or a module in the package.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With