--It's hard to bring in the philosophy of "1 class 1 file" in other languages without understanding Python's packaging system.
――I often see the introductory article "You can write like this when you use modules and packages", but it's hard to see the discussion about how it is supposed to be used (especially what is __init__.py
?" do not know)
――I don't mean to force it, isn't it like this as a base? I want to talk
If there is something like "Write this article or document properly and Adaroga", I would be grateful if you could let me know.
In languages such as Java and C # that are constrained by object orientation, I think it is customary to write one public class per file.
But in python, ~ .py
are all modules, and modules are a set of features they provide. I think a module can have multiple classes.
For example, an image of writing all entity classes in Django's models.py (the default module that implements ORM entity classes).
models.py
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
It may be a rare case in practice that this number of lines fits, but is it so beneficial to separate a class of at most a few lines into a separate file? Of course, if the language changes, so does the common sense. I feel that it is different to treat 1 class 1 file as prescribed in python.
The biggest reason I feel that way is that it affects how I write ʻimport`.
For example, if the configuration is as follows
polls/models/
├─ __init__.py
├─ question.py ...Only Question is defined
└─ choice.py ...Only Choice is defined
To call each class, write:
from polls.models.question import Question
from polls.models.choice import Choice
question = Question()
choice = Choice()
Alternatively, you can write:
from polls import models
question = models.question.Question()
choice = models.choice.Choice()
You have created a dedicated namespace for each class, haven't you? I feel overkill.
It has the same structure as the tutorial.
polls/models.py
To call the class, write:
from polls.models import Question, Choice
question = Question()
choice = Choice()
Or you can import everything by using *.
from polls.models import *
question = Question()
choice = Choice()
#Whether or not to use this is another matter as it is no longer explicit where and what was imported.
I think it's a simple structure where Question``Choice
lives in the namespace polls.models
.
So why is there a function called a package? For example, the following reasons are possible
--The number of classes and functions has increased in the module --There are some classes and functions that are used only in modules. ――The class is getting bigger and I really want to split the file
If this happens, the visibility will be worse if you do not use the package, and you will not be able to keep things organized. Let's use the package to separate the modules. I think you need to think about how to cut a module in a package each time, depending on what the package is for.
The only important thing is that ** the importer should be able to access it as if it were a single module **.
__Init__.py
for thatFor example, suppose (although not so often) based on the example in the previous tutorial, each class became bloated, and helper functions that were used only in models came out, so the file was divided into packages.
polls/models/
├─ __init__.py
├─ question.py ...Question is defined
├─ choice.py ...Choice is defined
└─ helper.py ...Convenience function is defined
At this rate, if you want to call Question
, you have to write from polls.models.question import Question
. In other words, the way to write import changes compared to when it was one file. If this were a library, it would be a catastrophic change affecting the interface.
Therefore, add the following to the always empty __init__.py
.
It is convenient to write the target module from .
because it becomes a relative reference.
polls/models/__init__.py
from .question import Question
from .choice import Choice
# (I don't write helper because it is used only internally)
By writing this, you can clearly state that " Question
Choice
is in the polls.models
namespace! ", And you can write import as it is.
from polls.models import Question, Choice
question = Question()
choice = Choice()
――I want to make the namespace granularity appropriate, and it's a bit strange to define a namespace just for one class.
--If you want to make a package, you should write something that is referenced from the outside in __init__.py
.
Of course, some libraries are designed to directly refer to modules in the package. Probably a huge library like a framework. Even so, the end packages are organized with the user in mind. It may be helpful to read such code.
Recommended Posts