Manual:コーディング規約/Python

This page is a translated version of the page Manual:Coding conventions/Python and the translation is 48% complete.

このページでは、MediaWiki プロジェクトまたはサポート プロジェクトの一部である Python プロジェクト群のコーディング規約について説明します。

前文

まず、コード標準は単なるガイドラインであり、正当な理由がある場合は違反する可能性があることを忘れないでください。

  • 厳格な遵守のために、厳格な遵守よりも読みやすさと自明性を目指してください。
  • コードは、書かれるよりもはるかに頻繁に読まれます。
  • 既存のコードと一貫性を保ちつつ、最善の判断を下してください。 既存のコードを修正するのがそれほど難しくない場合は、ページの編集は大胆に

この文書で網羅されていないものについては、一般的な方法について Python Enhancement Proposal 0008 を参照してください。 以下の節は、ほとんどの場合、PEP8 の最も一般的に参照される部分の要約です。

Python のバージョン

The minimum supported version is 2.7, but in special cases it is okay to support older versions.

Python 2.7 is no longer maintained as of 2020.

If you have not already, you should change to Python 3 for local development.

空白類

Lines should be indented with 4 spaces.

Lines at the end of files should end with a newline, just like every other line in the file.

Try to keep lines under 80 characters long, but aim for readability and obviousness over strict adherence for the sake of strict adherence. Shorter lines are just a general side effect of good idiomatic Python - short but properly scoped descriptive names, avoiding staircase code, etc. When splitting up lines, pick the most obviously unambiguous method possible for the situation.

モジュールの構造

The standard way to distribute Python modules is to create a setup.py file and leverage a library called "distribute". There are modules that will generate the structure of a base project for you, a deprecated one is paster create which is no longer maintained. A replacement is pythong.

In general module structure should look like this:

newproject
├── bin
├── distribute_setup.py
├── docs
├── newproject
│     └── __init__.py
├── setup.py
└── tests
       ├── __init__.py
       └── newproject_tests.py

インポート

Within a file it's generally a good idea to organize your imports in some fashion. Typically alphabetical order is favored, but this can become unwieldy when importing a large number of libraries. To help avoid this, it's good to separate out imports in this fashion, with each block separated from the others by an empty line:

  • Standard library imports
  • Third party imports
  • Your library imports
import os
import re
import sys

import pymongo
from sqlalchemy import create_engine, exceptions

from mymodule import MyCustomException, models, views

Here are some patterns to avoid:

import sys, os # 同じ行で異なるモジュールをインポート
from sqlalchemy import * # * をインポートしないでください
from .models import util # 相対的なインポートではなく完全修飾名を使用してください
Imports expanded example

Here is a more detailed abstracted version (the comments are just for explanation purposes):

# stdlib モジュールの完全インポート、アルファベット順
import a_stdlib_module
import b_stdlib_module

# stdlib モジュールの下位モジュールのインポート、上下と左右の両方でアルファベット順
from another_stdlib_module import a_stdlib_submodule, b_stdlib_submodule
from c_stdlib_module import another_stdlib_submodule, last_stdlib_submodule

# サード パーティ モジュールの完全インポート、アルファベット順
import a_third_party_module
import b_third_party_module

# サード パーティ モジュールの下位モジュールのインポート、上下と左右の両方でアルファベット順
from another_third_party_module import a_third_submodule, b_third_submodule
from c_third_party_module import another_third_submodule, last_third_submodule

# 現在のアプリケーション モジュールの完全インポート、絶対インポートでアルファベット順
import myapp.a_module
import myapp.b_module

# 現在のアプリケーション モジュールの下位モジュールのインポート、上下と左右の両方でアルファベット順
from my_app.another_module import a_submodule, b_submodule
from my_app.c_module import another_submodule, last_submodule

Docstrings and function annotation

Generally all but the simplest functions should have docstrings. These are standardized in PEP 257

def fractionize(first, second=1):
    """
    2 つの数値の分数の文字列表現を作成する。

    キーワード引数:
    first -- 分数の分子
    second -- 分数の分母 (0 以外のあらゆる値)
    """
    return "{0} / {1}" % (first, second)

This makes it possible to automatically generate docs, as well as use Python's built-in help function.

In Python 3.3 and above PEP 3107 specifies syntax for function annotations.

Function annotations do not have a completely set use case, but a common emerging case is for improved help docs and for type annotation.

def parse(source: "the original document",
          lang: "使用するマークアップ構文 [md|rst|textile]",
          force: "構文エラーを無視するかどうか"):

命名の競合

Conflicting with builtins is a somewhat common problem. There are some builtin names (like hash and id) that you may want to use in your code. The PEP8 way to deal with these conflicts is by appending an underscore to the name, such as hash_ or class_ (although if you're naming a variable class_ that may be a code smell).

If you find yourself in conflict with the name of some part of another module, import as is your friend.

from sqlalchemy import exceptions as sa_exceptions
from mymodule import exceptions as my_exceptions

関連項目