I'm trying to structure my app in Python. Coming back from C#/Java background, I like the approach of one class per file. I'd like my project tree to look like this:
[Service]
[Database]
DbClass1.py
DbClass2.py
[Model]
DbModel1.py
DbModel2.py
TheService.py
[ServiceTests]
[Database]
DbClass1Tests.py
DbClass2Tests.py
[Model]
DbModel1Tests.py
DbModel2Tests.py
TheServiceTests.py
Is it possible to create packages/modules in such a way so that packages work like Java's packages or .NET's namespaces, i.e. in DbModel1Tests.py:
import Service.Model
def test():
m = DbModel1()
In Python there is rule of one module=one file. In Python if you restrict yourself to one class per file (which in Python is not prohibited) you may end up with large number of small files – not easy to keep track. So depending on the scenario and convenience one can have one or more classes per file in Python.
The rule is this: a module is the unit of reuse. Everything in Python libraries and other Python applications is either a module or a package of modules. There is no limit on how many classes one can put in a file or a module.
A Python Module can be a simple python File (. py extension file), i.e., a combination of numerous Functions and Global variables. A Python Package is a collection of different Python modules with an __init__.py File. __init__.py Python File works as a Constructor for the Python Package.
This is not possible with the pip. All of the packages on PyPI have unique names. Packages often require and depend on each other, and assume the name will not change. Even if you manage to put the code on Python path, when importing a module, python searches the paths in sys.
Q1. You can use the 1 class per file style in Python, but this is unusual.
Q2. you'd have to use from Service.Model import *
and do some stuff in Service/Model/__init__.py
which is generally frowned upon. Avoid import *
in Python
My personal advice on this: Python is not C#/Java. Trying to bend it to make it look like $other_language will cause frustration and poor user experience.
Keep in mind that:
Service.Model.DbModel1 import DbModel1
looks bad. Prefer from service.model import DbModel1
: avoid uppercase letters in file names and directory names, and group classes / functions logically in files (rather than grouping them in directories as you would do with the 1 class per file system.) In my opinion, for 1: I don't see why not. I think, regardless of language this is a good idea as it provides you with a quick overview of what is to be found in a file when you know there will be only a single class in it. I would make a small exception for helper classes though, but as Python allows nested classes this can also be done quite nicely.
For 2: possible as well. In your example though, you simple load the module, thereby making its classes and functions available by the full namespace.
So, if you say import Service.Model
, you can only access the class by using m = Service.Model.DBModel1()
.
To import things into the current namespace, do a from Service.Model import *
(or from Service.Model import DBModel1
if you only need that class). Then you can do as you currently do: m = DBModel1()
.
You can have one class per module, but this is not required. I would say that it's more related to the length of each module (keeping them not too long is always a good idea).
Now, about your structure:
__init__.py
file in each sub-folder.from Service.Model import DbModel
and use this as you wrote: m = DbModel1.DbModel1Class()
Notes:
service.model.dbModel1.DbModel1()
.from Service.Model import DbModel1
to directly import class from DbModel1
module. This can be done through correct setting of __init__.py
content (I don't know how to configure it exactly). Some more informations here.
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