Reputation: 4206
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()
Upvotes: 6
Views: 5548
Reputation: 609
A python system is a set of modules, each module has a target, so you need use the most suitable approach to reach the target, it includes a class per module or a mix of functions and classes per module.
Upvotes: 0
Reputation: 13645
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.) Upvotes: 13
Reputation: 2822
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.Upvotes: 3
Reputation: 9474
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()
.
Upvotes: 4