Python♪基本:コメントアウトと、インデントやエスケープシーケンス

この記事では、「コメントアウト」「複数行のコメントアウトもどき」「エスケープシーケンス」の説明をします。メインはコメントアウトの説明ですが、ひょっこり、「エスケープシーケンス」の説明が入っています。どのように、「エスケープシーケンス」が「コメントアウト」に関係するのか、楽しみにしながら読み進めてください。

前の記事では、中1のゆうちゃんに、if文の基本的な内容を説明しました。if文がわかるとプログラミングの幅が広がるので、if文を使ったプログラムを説明したいという気持ちもあるのですが、今回の記事ではコメントアウトについて説明します。プログラミングが長くなると、コメントアウトがなければ、自分の書いたコードすら、あとで解読不能になります。

プログラミングの説明記事を書く側としては、サンプルコードの中にコメントを追加するために、もっと早く説明したかったのですが、if文でインデントを理解したあとに説明したかったので、このタイミングを待っていました。

0.ゆうちゃんとPythonシリーズ

この記事は「ゆうちゃんとPythonシリーズ」の記事です。一連の記事は、以下のリンク集を参照してください。

中学生のゆうちゃんとPythonシリーズ

なお、それぞれの記事は、シリーズの中でそれまでに習った文法を使ってサンプルコードを考えています。実際には、もっと、効率のよい書き方があるかもしれませんが、ご了承ください。

1.コメントアウト

Pythonでは、コードの中に半角の「#」(ハッシュタグ)を使用すると、「#」を記述した行の「#」以降のコードを無効にできます。例えば行の最初を「#」にすると、その行のコードはすべて無効になります。このように、「#」のような特定の記号を用いて、コードの一部を無効にすることを「コメントアウト」といいます。コメントを書くことがコメントアウトではありません。

 コメントアウトは、主に以下のような場合に使われます。

(1)コードを説明するコメントを挿入する

コードが命令文の羅列だけでは、あとで読み返したり、他の人がコードを読む場合に読みにくい場合があります。そのような場合にはコードを説明するコメントをコメントアウトの機能を使って挿入します。例えばコード01のように「r:球の半径(mm), a:球の表面積(cm2), v:球の体積(cm3)」というコメントをコメントアウトによって挿入すれば、コードの中の変数が何を意味するのかが明確になります。この例では、半径の単位は(mm)なのに対して、体積は(mm3)ではなく(cm3)となっていることがわかります。

 ゆうちゃん、球の表面積は「酔っ払いの事情」、体積は「身の上に心配あ~るので参上」と覚えようね。きっと、もうすぐ習うよ。

#コード01
# r:球の半径(mm), a:球の表面積(cm2), v:球の体積(cm3)
r = 100
a = 4 * 3.14 * r ** 2 / 100
v = 4 * 3.14 * r ** 3 / 3 /1000
print('a=',a, 'v=',v)
#出力01
a= 1256.0 v= 4186.666666666666

以下、色々なところでコメントアウトしてみました。「#」によるコメントアウトは、行の途中からコメントアウトすることもできます。また、文字列の場合は、文字列の中に単独で「\」を書くことができないなどの制約がありますが、「#」によるコメントアウトでは、記述できない符号などはありません。更に、インデント幅も自由なので、他の行にインデント幅をそろえる必要もありません。ただし、インデントに全角スペースは使えませんので、半角スペースやタブを使います。

#コード02
# r:球の半径(mm), a:球の表面積(cm2), v:球の体積(cm3)
r = 100 #命令文の後ろにコメントをつけることもできる
#「#」の後にはなんでも記述できる。「#」「\」「'」「''」などもo.k.
a = 4 * 3.14 * r ** 2 / 100 
v = 4 * 3.14 * r ** 3 / 3 /1000
print('a=',a, 'v=',v)
    #インデントも自由。でもインデントに全角スペースはダメ

(2)バグを見つける作業(デバッグ)で、一時的に一部のコードを無効にする

バグを見つける作業(デバッグ)を行う場合、故意に一部のコードを無効にして、その影響を確かめたい場合があります。そんなときに、無効にしたい行を行ごと消去し、動作確認後に再び同じコードを記入するのは大変です。そこで、そのような場合に、行の最初に「#」を挿入してコメントアウトし、動作確認後に、「#」を消して命令文を復活すれば、少ない労力でデバッグを行うことができます。

2.複数行のコメントアウトもどき

さて、それでは、複数行のコードを一度にコメントアウトするにはどうすればよいのでしょうか。

実は、Pyhonには複数行のコードを一度にコメントアウトする機能はありません。そこで、その代用として、無視したいコードの前後に「'''」(3つの半角シングルクォーテーション)や、「"""」(3つの半角ダブルクォーテーション)を記述することが慣例的に行われています。

 それでは、なぜ、「'''」や「"""」で代用できるのでしょうか。それを理解するには、複数行にわたる文字列の記述方法と、文字列のみが記述された行の実行結果について知る必要があります。

(1) 複数行の文字列の記述

 改行のない文字列は、「'aaabbbccc'」「"aaabbbccc"」のように、文字列にしたいコードの前後に「"」や「'」を記述することは以下の記事で説明しましたが、複数行にわたる文字列はどのように記述すればよいのでしょうか。

Python♪基本:まず、最初はint型、float型、str型と算術演算子ですね。

それには、主に以下の(a) (b)の方法があります。

(a)「'''」や「"""」を用いて複数行の文字列を記述する

複数行にわたる文字列の前後に「'''」(3つの半角シングルクォーテーション)や、「"""」(3つの半角ダブルクォーテーション)を記述することによって、複数行にわたる文字列を表現することができます。
例えば、コード03のように改行された文字列の最初と最後に「'''」を挿入すると複数行の文字列を表現することができます。2~4行目は1つの文字列です。

#コード03
'''aaa
bbb
ccc'''

(b) エスケープシーケンスを用いて複数行の文字列を記述する

例えば「改行」とは「そこで行を変えること」ですから、改行を通常の文字列で表せといわれても困ってしまいます。しかし、実は改行も「\n」という文字列で記述することができます。

「\n」のような特殊な文字や機能を表す文字列のことをエスケープシーケンスといいます。また、エスケープシーケンスの頭についている「\」は、特殊な意味をもつことを示す記号で、エスケープ文字といいます。したがって、コード03は、以下コード03bのように書き換えることができます。

#コード03b
'''aaa¥nbbb¥nccc'''

なお、「\」は、フォントによっては表示が円マーク「¥」であったり、バックスラッシュ「\」であったりしますが、フォントによる表記の違いだけですので同じものです。使っているPCやソフトによって表示が違う場合がありますが、気にしないようにしましょう。なお、バックスラッシュ「\」とスラッシュ「/」は違う文字ですので区別しましょう。

「\n」の使い方の例として、例えば、コード04のように、「aaa」「bbb」「ccc」の間に\nを挿入すると、それぞれ\nの部分で改行されます。統合開発環境のSpyderで入力する場合には、3行目のように「円マーク」ではなく、「バックスラッシュ」になっています。

#コード04
'aaa¥nbbb¥nccc'
'aaa\nbbb\nccc'

「\n」は、「n」のような普通の文字の前にエスケープ文字「\」をつけて、特殊な文字や機能を表すことができるのがエスケープシーケンスですが、逆に特殊な意味をもつ文字(例えば「\」)をただの文字として扱うためのエスケープシーケンスもあります。それが、「\\」「\”」「\’」です。

具体例で説明すると、コードの中で「’」を記述する場合、以下の2つのケースが考えられます。
 ①「’」で挟んだ部分が文字列であることを示す特別な意味をもつ記号。
 ②特別な意味はなく単純に「’」と表示したい。

Pythonでは、「’」を単独で使用すると、①の意味になってしまいます。つまり、「aaa’bbb」を出力したい場合に コード05の3行目のような記述をしても、「aaa」と「bbb」の間の「’」は、特別の意味がある記号と判断されます。つまり、「print(‘aaa’bbb’)」では「’」が3つあるため、どこからどこの範囲が文字列なのかわからず、エラーになります。

また、4行目も「\」という特殊な意味をもつ文字を文字列に含んでしまっているためにエラーになります。

#コード05
#エラーになる例
print('aaa'bbb')
print('aaa¥bbb')

そこで、コード05は、コード06のように書き換える必要があります。「’」の前に「\」をつけることで、「\’」は特別な意味をもつ「’」ではなく、ただの「’」であることを示します。つまり、「print(‘aaa¥’bbb’)」と記述することで、出力は「aaa’bbb」となります。

同様に「\」も単独ではエラーになりますので、「\\」とします。すると、出力06のように単独では出力できない文字を出力することができるようになります。

#コード06
print('aaa¥'bbb')
print('aaa¥¥bbb')
#出力06
aaa'bbb
aaa¥bbb

「\n」のときと同様に、「\\」「\”」「\’」の頭につける「\」も「エスケープ文字」と呼びます。

なお、特殊な文字や機能を表す「\n」はエスケープシーケンスですが、特殊な機能を打ち消す「\\」「\”」「\’」はエスケープシーケンスではないという分類の仕方もあるようです。ただし、プログラミング文法の解説では、どちらもエスケープシーケンスとして扱う場合が多いようです。

(2) 文字列のみで記述された行の実行結果

Pythonの対話モードでは、例えば文字列’abc’を入力して、Enterキーを押せば、その文字列をおうむ返しで返してきます。また、「1 + 2」と入力すれば、計算結果の「3」を返してきます。

それでは、この「’abc’」や「1 + 2」をPythonのコードとしてソースファイルに保存し、そのソースファイルを実行するとどうなるのでしょうか。試してみると、対話モードの場合と違い、この部分は無視されます。Pythonでは、ソースファイルを実行する形式で使用する場合、文字列や数式、定義された変数、半角の空白などを単体で記述してもエラーにならず、その行は、実質的には何もしない行になります。

#コード07
'abc'   #文字列だけの行は実質的にはなにもしない
1 + 2   #数式だけの行は実質的にはなにもしない
a = 5
a   #定義された変数だけの行は実質的にはなにもしない
    #半角の空白やタブだけの行は実質的にはなにもしない

(3) 文字列のみの行でも文法的に誤った記述はn.g.

「’abc’」や「1 + 2」といった行は、何もしない行ではありますが、文法的に誤った記述をするとエラーになります。例えば、「5/ 1」は問題ありませんが、コード08の10行目のように「5/ 0」ではゼロで除算しているためエラーになります。また、インデントについても、通常の命令文と同様のルールでインデント幅を設定しなければなりません。8行目のように、その行だけインデントを増やすとエラーになります。

#コード08
'r:球の半径(mm), a:球の表面積(cm2), v:球の体積(cm3)'
r = 100
a = 4 * 3.14 * r ** 2 / 100
v = 4 * 3.14 * r ** 3 / 3 /1000
print('a=',a, 'v=',v)
'コメント:これはo.k.'
    'コメント:インデント幅はそろえる必要があるため N.G.'
5/1 #実質的にはなにもしないが、エラーにならない。
5/0 #ゼロで除算しているので、エラーになる。

(4) 複数行のコメントアウトもどきのインデント

ここまで読めば、「なるほど」と思った人がいるかもしれませんが、コードの前後に「'''」(3つの半角シングルクォーテーション)や、「"""」(3つの半角ダブルクォーテーション)を記述する方法は、実際にはコメントアウトではなく、複数行の文字列を単体で記述しているだけなのです。したがって、「#」の場合と違い、インデント幅に注意する必要があります。また、「'''aaa\bbb'''」という記述もエラーになります。この場合、エスケープシーケンスを用いて「'''aaa\\bbb'''」とする必要があります。

一方、「#」は、「#」以降になにを記述してもエラーになりません。したがって、「#’aaa\bbb’」でもエラーになりません。

さて、ここで問題です。コード09はエラーになりますが、なぜ、エラーになるのでしょうか。

#コード09
a = 0.5
if a < 1:
'''aが1よりも小さい時に下のprint文を実行する。
    aが1以上のときには実行しない'''
    print('aは1より小さい')

それは、if文の影響範囲ある4~6行目はインデントをそろえる必要がありますが、4行目はインデントがないのに対して、6行目は半角スペース4個分のインデントがあり、インデント幅がそろっていないからです。

そこで、コード10のように、インデント幅をそろえればエラーになりません。

#コード10
a = 0.5
if a < 1:
    '''aが1よりも小さい時に下のprint文を実行する。
    aが1以上のときには実行しない'''
    print('aは1より小さい')

一方、コード11やコード12もエラーになりません。4~5行目は複数行にまたがってはいますが、1つの文字列です。したがって、文字列の最初の4行目だけインデントをそろえておけば、5行目はインデントをそろえる必要はないのです。

#コード11
a = 0.5
if a < 1:
    '''aが1よりも小さい時に下のprint文を
aが1以上のときには実行しない'''
    print('aは1より小さい')
#コード12
a = 0.5
if a < 1:
    '''aが1よりも小さい時に下のprint文を
                        aが1以上のときには実行しない'''
    print('aは1より小さい')

いかがでしょうか。コメントアウトといっしょにエスケープシーケンスを紹介したのは、以上のような流れで説明をしたかったからです。本当は「#」だけ覚えれば、しばらくは困らないのかもしれませんが、少し、掘り下げてみました。

なお、「#」によるコメントは、命令文と同じ行の後ろに記述するのではなく、1行使ってコメントアウトすることをが推奨されているます。ただ、私は短いコメントならば、命令文のあとに記述するのもありだと思います。状況に応じて見やすいコードの記述を心がけましょう。

おもしろかったのは、ゆうちゃんは、命令文の次の行にコメントをつけていたことです。「普通、前にかくよ~」「えっ、そうなの!」と、目が点になっていました。後ろにコメントをつけるなんて、私は想像すらしなかったけれど、説明を後ろに記述するというのも、筋としては間違っていない気がします。常識や慣例にしばられていると見えなくなってしまうものがあるのね。

でも、ゆうちゃん、コメント文は前に書こうね。(ふっふっふっ、ゆうちゃん、常識や慣例に縛られた世界へようこそ・・・)

3.まとめ

サンプルプログラムを使って解説したので長くなりましたが、まとめると簡単です。サンプルコード09~12はよく見比べて、間違えないようにしましょう。

(1)「#」を使ってコメントアウト

Pythonでは、コードの中に半角の「#」(ハッシュタグ)を使用すると、「#」を記述した行の「#」以降のコードを無効にできます。例えば行の最初を「#」にすると、その行のコードはすべて無効になります。このように、「#」のような特定の記号を用いて、コードの一部を無効にすることを「コメントアウト」といいます。コメントを書くことがコメントアウトではありません。

(2) 複数行のコメントアウトもどき

Pyhonには複数行のコードを一度にコメントアウトする機能はありません。そこで、その代用とPythonでは、無視したいコードの前後に「'''」(3つの半角シングルクォーテーション)や、「"""」(3つの半角ダブルクォーテーション)を記述することが慣例的に行われています。ただし、複数行の文字列の最初の行は、インデント幅に注意する必要があります。また、「#」の場合と違い、「\」の単独使用などはできませんので、使いたい場合にはエスケープシーケンスを使う必要があります

(3) エスケープシーケンス

改行のように通常の文字列では表現できないものも「\n」という文字列で記述することができます。「\n」のような特殊な文字や機能を表す文字列のことをエスケープシーケンスといいます。また、エスケープシーケンスの頭につけ、特殊な意味をもつことを示す「\」はエスケープ文字といいます。

なお、「\n」は、「n」の前にエスケープ文字「\」をつけて、特殊な文字や機能を表しますが、逆に特殊な意味をもつ文字(例えば「\」)をただの文字として扱うためのエスケープシーケンスもあります。それが、「\\」「\”」「\’」です。

なお、特殊な文字や機能を表す「\n」はエスケープシーケンスですが、特殊な機能を打ち消す「\\」「\”」「\’」はエスケープシーケンスではないという分類の仕方もあるようです。ただし、プログラミング文法の解説では、どちらもエスケープシーケンスとして扱う場合が多いようです。

4.例題

それでは、今回の記事の例題では複数行の文字列を出力してみます。print()を3回使って出力すれば簡単なのですが、今日、勉強したことの復習として、print()を1回だけ使って複数行の文字列を出力してください。ヒントとしてprint(文字列)という書式になるのですが、print()の括弧の中の文字列の書き方を工夫してください。

(1) 例題1 複数行の文字列

'''」か「"""」を用い、print()を1回だけ使って、出力13のように「あんぱん、メロンパン、食べたい」を3行に分けて出力しましょう。

#出力13
あんぱん
メロンパン
食べたい
解答を表示する

以下のようなコードになります。できましたか?

#コード13
print('''あんぱん
メロンパン
食べたい''')

(2) 例題2 エスケープシーケンス

エスケープシーケンスを用い、print()を1回だけ使って、出力14のように「セロリ、ピーマン、食べたくない」を3行に分けて出力しましょう。

#出力14
セロリ
ピーマン
食べたくない
解答を表示する

¥nが改行を意味するエスケープシーケンスです。

#コード14
print('セロリ¥nピーマン¥n食べたくない')

私が実際に購入した教材のご紹介

以下、私が実際に購入したPythonの教材をまとめてみました。 Pythonを学習する上で、少しでもお役に立つことができればうれしいです。

Python♪私が購入したPythonの書籍のレビュー

UdemyのPythonの動画講座を書籍を買う感覚で購入してみた