In ruby it is conventional to define a class inside the file of the same name. Nesting can be done by making a folder of the same name as the file.
+--lib
+--broccoli.rb
+--broccoli/
+--broccoli_powers.rb
+--broccoli_powers/
+--green.rb
I'm relatively new to python, so I'm trying to figure out how to generate the equivalent structure in python (but I want it to be "pythonic"). The main reason things can't be structured the same as in ruby is that you cannot have a module and package with the same name:
this won't work -- no way to get at broccoli.py and broccoli:
+--lib
+--broccoli.py
+--broccoli/
+--broccoli_powers.py
One way around this is to define an eponymous class in the __init__.py of the folder:
+--lib
+--broccoli/
+--__init__.py # <- define "class Broccoli" here
+--broccoli_powers.py
Now, I can use the Broccoli class like this:
from broccoli import Broccoli
And I could get at the BroccoliPowers class like this:
from broccoli.broccoli_powers import BroccoliPowers
But if I want to go deeper into the broccoli_powers namespace then I would need to move broccoli_powers.py into the __init__.py of the broccoli_powers folder like this:
+--lib
+--broccoli/
+--__init__.py # <- class Broccoli
+--broccoli_powers/
+--__init__.py # <- class BroccoliPowers
+--green.py
That's not as bad as it seems because the BroccoliPowers class is still accessible with the exact same invocation as before: "from broccoli.broccoli_powers import BroccoliPowers".
I don't like tucking substantial amounts of code into __init__.py files, but it is natural for me to organize my code into classes, and it seems natural to nest classes. What is the "pythonic" way to do this?
An alternative approach that I've considered for when I want to nest is moving the class definition to some file (say "cls.py" or "klass.py") and importing that in the __init__.py file namespace, like this:
+--lib
+--broccoli/
+--__init__.py # <- "from cls import Broccoli"
+--cls.py # <- define "class Broccoli" here
+--broccoli_powers.py
That achieves the same effect (I can access the Broccoli class as expected: "from broccoli import Broccoli") and I am not putting substantial amounts of code inside the __init__.py file.
What is the pythonic way to nest in this fashion? What am I missing?