コメントとはプログラマーがコードに付加するメモのことで、そのコードがどのように動作するかを記述します。実際にコードを動かすコンパイラやインタープリタからは無視されますが、ソフトウェアのプロジェクト管理においては極めて重要です。

コメントは他のプログラマーに対してPythonコードの内容を伝えると同時にプログラマー自身にとっても、なぜそのような選択をしたかの備忘録となります。将来保守するプログラマーは、コメントによりソフトウェアの背後にある設計上の取捨選択を理解でき、コードのデバッグと更新が容易になります。

コメントは主に開発者のためにありますが、効果的なコメントの記述は優れたドキュメントの作成につながり、コードの利用者にも恩恵があります。PythonプロジェクトのSphinxのようなドキュメントジェネレータを使用すれば、コードのコメントからドキュメントのコンテンツを作成できます。

この記事ではPythonのコメントについて詳しく見ていきます。

Pythonのコメント

Python PEP 8スタイルガイドには、コメントを書く際の注意点がいくつか挙げられています。

  • コメントは常に完全で簡潔な文章にする
  • 理解しにくいコメントや不正確なコメントがあるよりは、コメントがまったく無いほうがマシ
  • コメントはコードの変更を反映するために定期的に更新する
  • コメントが多すぎると紛らわしく、コードの質が低下する(コードの目的が明らかであれば、コメントは必要なし)

Pythonでは、# 記号で始まる行がコメントとして宣言されます。Pythonインタプリタはコードの中で # 記号に出会うと、何のエラーも出力せずに記号以降を無視します。コメントを宣言する方法には、インラインコメントとブロックコメントの2つがあります。

インラインコメント

インラインコメントは変数や簡単な操作方法を説明する短い文で、コードと同じ行に記述します。

border = x + 10  # Make offset of 10px

このコメントは、コードと同じ文中でコードの機能を説明しています。

ブロックコメント

ブロックコメントは、コード内の複雑なロジックの記述に使用されます。Pythonのブロックコメントはインラインコメントと同様の記法ですが、コードとは別の行に記述される点で異なります。

import csv
from itertools import groupby

# Get a list of names in a sequence from the csv file
with open('new-top-firstNames.csv') as f:
    file_csv = csv.reader(f)

# Skip the header part: (sr, name, perc)
header = next(file_csv)
    
# Only name from (number, name, perc)
persons = [ x[1] for x in file_csv]

# Sort the list by first letter because 
# The groupby function looks for sequential data.
persons.sort(key=lambda x:x[0])
data = groupby(persons, key=lambda x:x[0])

# Get every name as a list 
data_grouped = {}
for k, v in data:
    # Get data in the form 
    # {'A' : ["Anthony", "Alex"], "B" : ["Benjamin"]}
    data_grouped[k] = list(v)

注意)ブロックコメントは説明するコードの上に記述します。Python PEP8スタイルガイドでは1行のコードに含まれる文字数を79文字までとしていますが、インラインコメントではしばしばこの長さを超えてしまいます。ブロックコメントを使用すれば、コードの説明を別の行に記述できます。

複数行のコメント

Pythonはネイティブでは複数行のコメントをサポートしていません。つまり複数行を定義した特別な規定はありません。ただし複数行にまたがるコメントはしばしば使用されます。

各行の先頭に # を付けることで、複数の単一行コメントから複数行コメントを作成できます。

# interpreter 
# ignores
# these lines

また、複数行の文字列構文も使用できます。Pythonでは、複数行の文字列を """(三重の二重引用符)または '''(三重の一重引用符)で囲んで定義できます。

print("Multi-Line Comment")
"""
This
String is 
Multi line 
"""

上のコードで複数行の文字列は変数に代入されていないため、コメントのように動作します。実行時、この文字列はPythonからは無視され、バイトコードにも含まれません。上のコードを実行すると、次のように出力されます。

Multi-Line Comment

特殊なコメント

Pythonのコメントにはコードを読みやすくする目的だけでなく、将来のコードを追加する予告や、ドキュメントの生成などの特別な目的もあります。

Pythonのdocstringコメント

Pythonのdocstringは、関数やクラスの使い方を説明する複数行のコメントです。高品質なdocstringsを作成することで、コードのドキュメントを改善できます。関数やクラスでの作業中に組み込みの help(obj) 関数を使用してdocstringによるオブジェクトの概要を表示できます。

Python PEP 257には、以下に示すようなPythonでの標準的なdocstringの宣言方法が記述されています。

from collections import namedtuple
Person = namedtuple('Person', ['name', 'age'])

 def get_person(name, age, d=False):
    """
Returns a namedtuple("name", "age") object.
Also returns dict('name', 'age') if arg `d` is True

Arguments:
name  – first name, must be string
age   – age of person, must be int
d     – to return Person as `dict` (default=False)

"""
p = Person(name, age)
if d:
    return p._asdict()
return p

上のコードでは、関数がどのように動作するかをdocstringで記述しています。このdocstringに対してSphinxのようなドキュメントジェネレータを使用すると、関数の利用者に対して使い方の概要を表示できます。

関数やクラスのシグネチャのすぐ下に定義されたdocstringは、組み込みの help() 関数を使用しても取得できます。help() 関数は、オブジェクト名や関数名を引数として受け取り、関数のdocstringを出力として返します。上の例では、help(get_person) を呼び出して、get_person関数に関連するdocstringを表示しています。-i を使用した対話型シェルで上のコードを実行すると、Pythonによってdocstringがどのようにパースされるかを見ることができます。python -i file.py と入力して、上のコードを実行してみてください。

コマンドラインインターフェースでパースされたPythonのdocstring
コマンドラインインターフェースでパースされたPythonのdocstring

help(get_person) 関数を呼び出すと、関数のdocstringが返されます。出力にはPythonが自動的に追加した関数シグネチャget_person(name, age, d=False) が含まれています。

また get_person.__ doc__ 属性を使用すると、docstringを取得してプログラムにより変更できます。上の例では「追加の新しい情報」を加えた後、2回目の help(get_person) 呼び出しで、これを表示しています。ただしこのように実行時、動的にdocstringを変更する必要性はまずありません。

TODOコメント

コードを書いていると、特定の行やブロック全体を改善のために強調したい場合があります。こうした作業はTODOコメントを使用してフラグ付けできます。TODOコメントは、コードの更新や変更を計画しているときや、コードの使用者や共同作業者に、ファイルのコードの特定部分が未実装であることを知らせたいときに役立ちます。

TODOコメントは疑似コードとしては書きません。未実装のコードの機能を簡単に説明するだけです。

TODOコメントと1行ブロックコメントは非常によく似ており、唯一の違いはTODOコメントがTODO接頭辞で始まる点です。

# TODO Get serialized data from the CSV file
# TODO Perform calculations on the data
# TODO Return to the user

重要な注意点として、多くのIDEはTODOコメントをプログラマー向けに強調表示しますが、PythonインタープリタはTODOコメントをブロックコメントとまったく同じように扱います。

Pythonのコメントのベストプラクティス

コメント記述の際には信頼性と品質確保のためにベストプラクティスに従うことが推奨されます。以下にPythonで質の高いコメントを書くヒントを挙げます。

当たり前のコメントを書かない

明らかな挙動を記述したコメントは、コードに何の価値も与えないため避けてください。例えば以下の通りです。

x = x + 4 # increase x by 4

このコメントは無意味です。コードが何をするのかを伝えるだけで、なぜそれが必要なのかが説明されていません。コメントでは、記述しているコードの「何」よりも「なぜ」を説明するようにしてください。

上の例を書き直すと次のようになります。

x = x + 4 # increase the border width

Pythonのコメントは短く簡潔に

コメントは短く、簡単に理解できるように記述してください。コメントは疑似コードではなく標準的な文章で書き、実際のコードを読まなくてもそのコードが何をするのかが大まかに分かるようにしてください。過度に詳細で複雑なコメントを書いてもプログラマーの仕事は楽になりません。例えば以下の通りです。

# return area by performing, Area of cylinder = (2*PI*r*h) + (2*PI*r*r)
def get_area(r,h):
    return (2*3.14*r*h) + (2*3.14*r*r)

このコメントには必要以上の情報があります。コメントはメインのロジックを説明するのではなく、コードの大まかな動きを記述してください。このコメントは、次のように書き換えられます。

# return area of cylinder
def get_area(r,h):
    return (2*3.14*r*h) + (2*3.14*r*r)

識別子の使用は慎重に

コメント中の識別子は慎重に使用してください。識別子の名前やケースを変更すると読み手が混乱します。例えば、以下の例です。

# return class() after modifying argument
def func(cls, arg):
    return cls(arg+5)

上のコメントでは、class と argument と記述していますが、どちらもコードには存在しません。このコメントは次のように書き換えられます。

# return cls() after modifying arg
def func(cls, arg):
    return cls(arg+5)

DRYとWET

コードを書くときは、DRY(Don’t repeat yourself=繰り返すな)の原則を守りましょう。WET(Write everything twice=同じコードを2度書く)は避けたいところです。

コメントを書くときも同じです。コードの説明に複数の文を使うことは避け、同じコードを説明するコメントは1つにまとめてください。ただし、コメントをまとめる際は注意が必要です。不用意に複数のコメントをまとめると、スタイルガイドに反した巨大なコメントになり、読み取りが困難になります。

コメントは、コード理解にかかる時間を短縮するものであることをお忘れ無く。

# function to do x work
def do_something(y):
    # x work cannot be done if y is greater than max_limit
    if y < 400:
      print('doing x work')

上のコードでは、コメントが不必要にバラバラになっています。これは1つのコメントにまとめられます。

# function to do x if arg:y is less than max_limit
def  do_something(y):
    if y in range(400):
        print('doing x work')

一貫したインデント

コメントは記述しているコードと同じレベルでインデントされていることを確認してください。そうでないとコードを追いかけるのが困難になります。

例えば以下のコメントは、インデントも位置も適切ではありません。

for i in range(2,20, 2):
# only even numbers
    if verify(i):
# i should be verified by verify()
        perform(x)

これは以下のように書き換えられます。

# only even numbers
for i in range(2,20, 2):
    # i should be verified by verify()
    if verify(i):
        perform(x)

まとめ

コメントは理解しやすいコードを書くための、重要な要素です。コメントを書く手間は、そのコードで将来作業する自分自身、または他の開発者にとってのかけがえのない投資となります。またコメントを書くことで、コードに対してより深い洞察が得られます。

この記事では、様々な種類のコメントとそれをいつ使うか、そして書くときのベストプラクティスなどPythonのコメントについて詳しく解説しました。

分かりやすいコメントの記述は一種のスキルであり、これの醸成に時間を投じるだけの価値は十分にあります。練習として、過去のプロジェクトに戻ってコメントを追加してみることをおすすめします。GitHubで十分なドキュメントのあるPython関連プロジェクトをチェックしてみるのも一つの手です。

Pythonプロジェクトを本番環境で稼働する準備ができたら、Kinstaのアプリケーションホスティングプラットフォームをご活用ください。GitHubからクラウドに数秒でコードをデプロイできます。

Vivek Singh

Vivek is a Python and Django developer who's always ready to learn and teach new things to fellow developers.