my question is about writing Python (3.x) packages and (sub-)modules and the correct usage of __init__.py
files to declare namespaces.
I used to code in C++, so I like to use a lot of separate files to organize projects. For example, (imo) if a module contains several classes, each of these should be in a separate file.
As I am inexperienced developing in Python, it is hard to formulate my thoughts in a simple question. So let's consider the following small python package as an example.
dir
|
+-- example
| |
| +-- script.py
|
+-- package
|
+-- __init__.py
|
+-- foo.py
|
+-- subpackage
|
+-- __init__.py
|
+-- bar.py
Let's have a look at the files.
package/foo.py
:
def foo:
print('foo')
package/subpackage/bar.py
:
def bar:
print('bar')
The following example/script.py
works fine.
import sys
sys.path.insert(0, '..')
import package
import package.subpackage
package.foo.foo()
package.subpackage.bar.bar()
I don't like to use package.foo.foo()
/ package.subpackage.bar.bar()
and would like to use package.foo()
/ package.subpackage.bar()
.
And I don't want to use from package.subpackage.bar import bar
, as I don't want to mix the namespace of subpackage into script.
I used the __init__.py
files to achieve that.
package/__init__.py
:
from package.foo import foo
package/subpackage/__init__.py
:
from package.subpackage.bar import bar
Is this a good python-like way to define namespaces? Or is there a better / common way to organize the file-system of a package in python. (I did not find a proper tutorial/example for this.)
In file package/subpackage/__init__.py
, why does it have to be:
from package.subpackage.bar import bar
and not:
from subpackage.bar import bar
?
This would result in the error:
Traceback (most recent call last):
File "script.py", line x, in <module>
import package.subpackage
File "..\package\subpackage\__init__.py", line x, in <module>
from subpackage.bar import bar
ImportError: No module named 'subpackage'
The __init__.py files are required to make Python treat directories containing the file as packages. This prevents directories with a common name, such as string , unintentionally hiding valid modules that occur later on the module search path.
Practical Data Science using Python So if you want to create a namespace, you just need to call a function, instantiate an object, import a module or import a package. For example, we can create a class called Namespace and when you create an object of that class, you're basically creating a namespace.
The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path.
The __init__.py file makes Python treat directories containing it as modules. Furthermore, this is the first file to be loaded in a module, so you can use it to execute code that you want to run each time a module is loaded, or specify the submodules to be exported.
Is this a good python-like way to define namespaces? Or is there a better / common way to organize the file-system of a package in python. (I did not find a proper tutorial/example for this.)
This is an okay way to setup a Python package. Only okay and not 'good' because of the contents of foo.py
and bar.py
.
I don't like to use
package.foo.foo()
/package.subpackage.bar.bar()
and would like to usepackage.foo()
/package.subpackage.bar()
.
In this case, you can't. And not mixing the name spaces is good reason to not do from package.subpackage.bar import bar
.
It would have been better if def foo(): ...
and def bar(): ...
were directly in __init__.py
. That way, you could have done package.foo()
and package.subpackage.bar()
. It could also have been done by using __all__
in init but import *
is also not considered good.
Or, the foo
and bar
packages should have had more in it like foo.function1
, foo.other_func
, bar.drink
, etc. which gives it more human-friendly understandable organisation.
Examples and references are not within scope for good StackOverflow questions but here are some, for a well thought-out question:
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