10. プログラマーの考え方を知ろう

この章では、実用的なプログラムを作る上で押さえておくと役に立つ話題を2つ紹介します。

  • プログラムの再利用

  • 命名

それぞれの話題でプログラマーの考え方を押さえたら、次章からはいよいよ実用的なプログラムを作ります。

10.1. プログラムを再利用する

皆さんの手元には、これまでに書いてきたプログラム(Pythonのファイル)がありますね。 例えば、6 章 の「順次の練習:挨拶するプログラム」では、 渡した名前の人への挨拶文を返す関数 aisatsu_bunaisatsu.py に作りました。

それでは、別のプログラムを書いている時に、 aisatsu_bun 関数が返すのと全く同じ挨拶文を返す関数を使う必要があるとなったら、どうしますか?

aisatsu_bun 関数をコピー&ペーストして、別のプログラムに定義するというやり方も浮かびますね。 ですが、プログラマーの考え方としては、すでにある aisatsu_bun 関数を 再利用する ことを考えます。

現在の aisatsu.py
1def aisatsu_bun(namae):
2    return f"{namae}さん、ごきげんよう^o^"
3
4
5namae = input("名前を入力してください:")
6print(aisatsu_bun(namae))

再利用の手順は2段階です。

  1. aisatsu.py読み込む

  2. aisatsu_bun 関数を呼び出す

1の読み込みについて解説します。 読み込んだ後の呼び出しは、関数の呼び出しと共通です。

10.1.1. プログラムを読み込む

10.1.1.1. import

読み込むには import 文を使います。 プログラマーは、プログラムを読み込むことを「プログラムをインポートする」とも言います。

import プログラム名 と書くと、指定したプログラムを読み込めます(例:import aisatsu)。 プログラム名の拡張子は不要です。

対話モードで試してみましょう。 カレントディレクトリが basic であることを確認してから、対話モードを起動してください。

aisatsu.py を読み込みます。 ファイルを読み込む処理系は、まずその ファイルを実行 します。

>>> import aisatsu  
名前を入力してください:

処理系が aisatsu.py を実行し、5行目の input 関数で入力待ちになりました。 名前を入力すると、残りが実行され、読み込みは完了します(print 関数による表示があります)。

>>> import aisatsu  
名前を入力してください:nikkie
nikkieさん、ごきげんよう^o^
>>>

対話モードのプロンプトが再度現れたら、読み込み完了です。 import 文を実行すると、処理系は aisatsu.pyaisatsu という 名前で扱える ようになります。 aisatsu.pyaisatsu_bun 関数は、aisatsu.aisatsu_bun とドットでつないで呼び出せます。

>>> aisatsu.aisatsu_bun("nao_y")  
'nao_yさん、ごきげんよう^o^'
>>> aisatsu.aisatsu_bun("susumuis")  
'susumuisさん、ごきげんよう^o^'

aisatsu_bun 関数を再利用できました!

10.1.1.2. 読み込むときに実行しない処理を指定する

aisatsu.py の読み込みで名前の入力が求められるのは少し使いづらいですよね。 そこで、import読み込むときには実行しないという分岐を追加 します。

aisatsu.py
1def aisatsu_bun(namae):
2    return f"{namae}さん、ごきげんよう^o^"
3
4
5if __name__ == "__main__":
6    namae = input("名前を入力してください:")
7    print(aisatsu_bun(namae))

aisatsu.py を変更したら、対話モードを一度終了してから再度開いて import します。

>>> import aisatsu
>>> aisatsu.aisatsu_bun("susumuis")
'susumuisさん、ごきげんよう^o^'

名前を入力せずに読み込めました!

追加した分岐について説明します。 これは ファイルをコマンドラインから実行したときのみ 実行される分岐です。

条件に使われている __name__変数 です。 前後にアンダースコアが2つずつ付いていますが、変数であることは変わりません。 この変数は、Pythonファイルが持つ特別な変数です。

  • コマンドラインからPythonファイルを実行する時、そのファイルの __name__ が指す値は、文字列の "__main__" と一致します

  • Pythonファイルを import する時、そのファイルの __name__ が指す値は、文字列の "__main__" とは一致しません

import でファイルを実行するときは 分岐を通らない ので、名前の入力が求められないのです。

コマンドラインで実行したときの挙動は変わっていません。

> python aisatsu.py
名前を入力してください:nikkie
nikkieさん、ごきげんよう^o^

if __name__ == "__main__": という分岐は、Pythonのファイルの中でよく使われます。

[発展] 読み込みの別のやり方: from import

別の import のやり方も紹介します。 from プログラム名 import 関数名 と書くと、読み込んだ関数をドットでつながず そのままの名前で 呼び出せます。

対話モードを開き直してから以下を実行してください。

>>> from aisatsu import aisatsu_bun
>>> aisatsu_bun("nao_y")
'nao_yさん、ごきげんよう^o^'

from import という書き方でも aisatsu.py実行されることは変わりません。 この書き方で読み込むと、aisatsu.pyaisatsu_bun 関数を aisatsu_bun という名前で扱えます。 どちらも使われるので、2通り頭に入れておくと、この後出てくるプログラムが読みやすいでしょう。

10.1.2. 再利用してプログラムを書く

学んだ import を使って、関数を別のプログラムで再利用してみましょう。 aisatsu.pyaisatsu_bun 関数を別のプログラムで使います。 import を使うファイルは aisatsu.py と同じディレクトリ(basic)の中に作ってください。

再利用の例
1from aisatsu import aisatsu_bun
2
3print(aisatsu_bun("読者の皆さん"))

再利用するのは、あなたが作ったプログラムだけにとどまりません。 他のプログラマーが作ったプログラム も再利用できます。

プログラマーが再利用できるように公開されたプログラムは「ライブラリ」と呼ばれます。 プログラミング言語には、よく使う処理がライブラリとして用意 されています。 Pythonにも「標準ライブラリ」があります。 Pythonと一緒にインストールされるので、皆さんの環境はすでに標準ライブラリは使える状態です。

[コラム] ライブラリは作品集と似ている

ライブラリという言葉には、作品集 という意味もあります。 作品集を入手するように、ライブラリもインストールして入手する必要があります。

作品集が1つ1つの作品から成るように、ライブラリも「モジュール」が集まってできます。 モジュールは、プログラムが書かれた ファイル です。

import 文を使うと、ライブラリにあるモジュール(ファイル)に書かれた関数や型を使えます。 作品集の中の作品から、特定の部分を参照するイメージです。

標準ライブラリに用意されたモジュールから、関数や型を import するだけで、様々な処理が使えます。

[発展] 標準ライブラリ以外のライブラリ

プログラミング言語に用意されたライブラリ以外にも、プログラマーが公開しているライブラリ がたくさんあります。 標準ライブラリだけでもかなり多くのことができますが、 標準ライブラリ以外のライブラリ(サードパーティーライブラリ)を使えば、文字通りあらゆることができる印象です。

サードパーティーライブラリは、ライブラリごとにインストール して、あなたの環境で使える状態にする必要があります。 プログラマーの世界には、「パッケージマネージャー」と呼ばれる、インストールを手伝ってくれるソフトウェアがあります。 # noqa サードパーティーライブラリを使う必要が生じたら、使い方を調べたり、質問したりしましょう。

[コラム] なぜ関数をコピー&ペーストしなかったのか

aisatsu.py を読み込む代わりに「aisatsu_bun 関数をコピーして、 使いたいファイルにペーストすればいいのではないか」と思ったかもしれませんね。 なぜそうしなかったのか、その理由は、似たコードが増えてしまうからです。

似たコードが増えると、変更が大変になります。 例えば aisatsu_bun 関数の返り値に含む顔文字を変更するとしましょう。 コピー&ペーストで増やした全ての aisatsu_bun 関数を変更しなければなりません。 1つ1つの修正は単純だと思うかもしれませんが、作業箇所が多いほど、作業漏れなどミスしやすくなります。

このように、コピー&ペーストは、プログラムの 変更しやすさを失わせ てしまいます。 変更しやすい状態を保つため、コピー&ペーストをせずに import で読み込みます。 これならば aisatsu_bun 関数の返り値を変えることになっても、読み込み元1箇所だけの変更で済みます。

プログラマーの世界には、DRY(ドライ。乾燥という意味のドライともかけている)という格言もあります。 Don't repeat yourself「繰り返してはならぬ」の略です。 繰り返しによる悪影響はみな知っているのです。

[コラム] ライブラリを使うのに気後れする必要はない

プログラマーの世界には、ライブラリを 他のプログラマーが使えるように公開する文化 があります。 この裏にあるのは、「自分にとって便利なライブラリは、他の誰かにとっても便利」という考え方です。 なので、プログラミングを始めたばかりでも、凄腕プログラマーが開発した便利なライブラリ をあなたのプログラムの中で使えます。

もしかすると、「まだまだ学び始めの自分が使っていいのか」と気後れするかもしれませんね。 敬意は必要ですが、遠慮は不要 です。 感謝を胸に、積極的に使いましょう。 ライブラリを使うと、あなたがプログラミングでできることが一気に増えます! この姿勢は「巨人の肩に乗る」と呼ばれ、プログラマーの世界で奨励されます。

もらいっぱなしが気になるのなら、いつの日かあなたの書いたプログラムが、 他の誰かの課題を解決するという形で、コミュニティにお返し すればいいのです。 他の誰かは、先を行く凄腕プログラマーに限らず、あなたの後に続く初学者でもいいのです。

ライブラリを使う際の心構えとして「お客さまにならない」ことをおすすめします。 ライブラリは完成した製品ではなく、プログラマーコミュニティのみんなで開発中 のプログラムです。 なにか問題に気づいたら、苦情を言うのではなく、「一緒に修正しよう」という姿勢で関わりましょう。

10.2. 名前は重要

プログラムの3大構造を学ぶ中で、変数や関数名は、日本語をローマ字にして付けました。 例えば aisatsu_bun 関数は「挨拶文(あいさつぶん)」のローマ字表記です。

実用的なプログラムを作る前に、名前を付ける際の考え方 を知りましょう。 また、英単語をつないだ 名前の付け方も紹介します。

10.2.1. 名前にはよい/悪いがある

実はプログラマーは、プログラムを書くよりも 他人が書いたプログラムを読む時間の方が多い です。 プログラムを読んで理解するときには、変数や関数名といった名前が手がかりになります。 名前を具体的にする ことで、プログラムを理解するまでの時間を短くできます。

よい名前とは、他のプログラマーがプログラムを読んで 理解するまでの時間を短くする 名前です。 よい名前は具体的な名前です。 変数であれば、指す値の意味を示す名前、関数であれば、処理の内容を示す名前 がよい名前です。

例えば、a = 1080 の変数 a はよい名前でしょうか? 指している値 1080 がどんな意味か分かりづらいですよね。 仮に、この値は合計を意味しているとしましょう。 goukei = 1080 と書き換えると、1080 という値が合計であることが伝えられます

「自分のプログラムを他のプログラマーに見せる機会がないから関係ない」とは考えないでください。 プログラムを読んで理解するプログラマーには、数週間〜数カ月先の(どんなプログラムかを忘れた)あなた自身 も含まれます。 未来の自分がプログラムをすぐに把握できるように、意味を説明する名前を付けていきましょう。 ここまでに登場したローマ字表記の名前も、意味を説明するような名前を選んでいました。

[コラム] よい名前についてもっと知る

よい名前を付けることは簡単そうに聞こえて奥が深いです。 プログラマーも苦労してきたようで、先人たちが数々の指針を残しています。

よい名前を付けたい場合、自己流でやるよりは、先人の残した指針を参考にする のをおすすめします。 例えば『リーダブルコード』という本で、先人の指針を学べます。

10.2.2. 変数や関数の名前は英単語で付ける

ここまで、名前をローマ字表記で付けたのは、初めてプログラミングをする上での障壁を小さくするための工夫です。 プログラマーは一般に、英単語を組合せて 名前を付けます。 本書の残りで登場するプログラムも、変数や関数名が英単語に変わります。

「英単語」と聞いて、「英語に自信がない」と思うかもしれませんが、心配いりません。 プログラムは英文ではないので、英文法の知識は必須ではありません。 英単語をつなげればいい のです。

名前は理解するまでの時間を短くすることが重要です。 なので、まず日本語で 具体的な名前を考えましょう。 具体的な名前が決まったら、単語ごとに英語に置き換え ます。 このとき、インターネット上の辞書サイトや、PCに内蔵された辞書アプリ(macOSの「辞書.app」など)の助けを得られます。

英文法としての誤りを心配する必要はありません。 十分具体的な英単語をつないだら、文法的に間違っていたとしても、プログラムを理解するまでの時間は短くなります。

[コラム] 英単語の意味を調べる習慣を付けよう

この本の目的はプログラミング入門ですから、英単語にどうしても苦手意識がある場合は、ローマ字表記の名前を使えばよいでしょう。 ですが、プログラミングに取り組む中では、英単語を完全に避けて通ることはできません。 例えば、ライブラリにある関数は、英単語で命名されていますし、皆さんから見て先輩のプログラマーたちは英単語で命名します。

英単語への苦手意識を払拭できると、プログラミングでも恩恵が得られます。 中学校や高校で習う英文法をやり直す必要はありません。 英単語の意味を個々に調べて 意味をつかめばいいのです。

意味を調べる習慣が付くと、ライブラリにある関数名から処理内容がつかめます。 また、他のプログラマーと一緒にプログラムを書く機会にも飛び込んでいきやすくなるでしょう。 英単語の意味を掴むようにすることで、プログラムを通したコミュニケーションができるようになるのです。

10.2.3. 例:挨拶のプログラムを書き変える

以上を踏まえ、aisatsu.py を書き直します。 ローマ字表記で具体的な名前になっているので、英単語に置き換えます。 「挨拶をする」は英語でgreetなので、ファイル名も greet.py に変えます。

greet.py
1def greeting(name):
2    return f"{name}さん、ごきげんよう^o^"
3
4
5if __name__ == "__main__":
6    name = input("名前を入力してください:")
7    print(greeting(name))
英単語を使って aisatsu.py を書き換え

変数/関数の役割

これまでのローマ字表記

英単語を使った表記

挨拶の言葉を返す

aisatsu_bun

greeting (挨拶の言葉という意味)

名前を表す

namae

name

ここまでに登場したプログラムを英単語を使って書き直すと練習になるでしょう。 また、ここまでのプログラムを何も見ずにスラスラと書けるようになれば、よい名前付けの習慣が身に付いています!

[発展] 命名での単語のつなぎ方

複数の単語を組合せて名前を付ける時、本書では アンダースコアでつないで きました(例:aisatsu_bun)。 この記法は、胴の長い蛇(snake)のように見えるため、「スネークケース」と呼ばれます。

単語をそのままつなげると、区切りが分からず読みにくいですよね(例: greentea)。 そのため、つなぎ方を考える必要があり、スネークケース以外のつなぎ方も考案されてきました。

  • ハイフン でつなぐ:green-tea (ケバブケース)

  • 続く単語の 先頭の文字を大文字にして つなぐ:greenTea (キャメルケース)

キャメル(camel)はラクダのことで、大文字がラクダのコブのように見えることから呼ばれています。

スネークケース、ケバブケース、キャメルケース、どれが使われるかはプログラミング言語ごとに異なります。 Pythonを書く場合は、スネークケースが多いです。

[コラム] 繰り返し読まないプログラムなら、よい名前にこだわらなくてもいい

具体的な名前を付けるのは、読んだときにプログラムをすぐに把握できるようにするためです。 もしそのプログラムを繰り返し読むことがないのなら、具体的な名前にこだわらなくてもよいでしょう。

繰り返し読まないプログラムの例は、新しく知ったことを対話モードで試すとき です(7 章 のコラム参照)。 新しく知った関数や書き方を把握するのが目的で、後から読み返すわけではありません。 そんなとき、私は ab のような「悪い」変数を使います。 ただし、把握した後にファイルに書くときは、指す値を具体的に示すよい名前になるように注意を払います。