Modules and packages in Python are "namespaces"

Motivation for writing this article

--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.

Disadvantages of separating files by class

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)

Excerpt from "Creating your first Django app, part 2"

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`.

Module import when 1 class 1 file

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.

When all classes are in one module

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.

Reasons to use packages

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 that

For 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()

So ** modules and packages are namespaces **

――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

Modules and packages in Python are "namespaces"
Python packages and modules
Organize python modules and packages in a mess
Understand Python packages and modules
MIDI packages in Python midi and pretty_midi
Python Basic Course (14 Modules and Packages)
nest cog in discord.py
Modules and packages in Python are "namespaces"
Summary of modules and classes in Python-TensorFlow2-
Write python modules in fortran using f2py
Stack and Queue in Python
Unittest and CI in Python
Get an abstract understanding of Python modules and packages
List method argument information for classes and modules in Python
A standard way to develop and distribute packages in Python
Introduction to Effectiveness Verification Chapters 4 and 5 are written in Python
Difference between list () and [] in Python
Difference between == and is in python
View photos in Python and html
Sorting algorithm and implementation in Python
Manipulate files and folders in Python
About dtypes in Python and Cython
Introductory Python Modules and conditional expressions
Assignments and changes in Python objects
[Python] What are @classmethods and decorators?
Check and move directories in Python
Ciphertext in Python: IND-CCA2 and RSA-OAEP
Hashing data in R and Python
Function synthesis and application in Python
Export and output files in Python
Reverse Hiragana and Katakana in Python2.7
Reading and writing text in Python
[GUI in Python] PyQt5-Menu and Toolbar-
Create and read messagepacks in Python
Regular expressions that are easy and solid to learn in Python
Upload and manage packages that are not in conda to anaconda.org
Overlapping regular expressions in Python and Java
Differences in authenticity between Python and JavaScript
Notes using cChardet and python3-chardet in Python 3.3.1.
Avoid nested loops in PHP and Python
Differences between Ruby and Python in scope
AM modulation and demodulation in Python Part 2
difference between statements (statements) and expressions (expressions) in Python
Eigenvalues and eigenvectors: Linear algebra in Python <7>
Python virtual environment and packages on Ubuntu
Implementation module "deque" in queue and Python
Line graphs and scale lines in python
[Python] Package and distribute your own modules
Implement FIR filters in Python and C
Differences in syntax between Python and Java
Check and receive Serial port in Python (Port check)
Search and play YouTube videos in Python
Difference between @classmethod and @staticmethod in Python
Difference between append and + = in Python list
Difference between nonlocal and global in Python
Write O_SYNC file in C and Python
Dealing with "years and months" in Python
Read and write JSON files in Python
Easily graph data in shell and Python
Private methods and fields in python [encryption]
Find and check inverse matrix in Python
Linear Independence and Basis: Linear Algebra in Python <6>
Call sudo in Python and autofill password
Summary of modules and classes in Python-TensorFlow2-