1.1 オブジェクトとクラス
今日は、Pythonでの典型的なプログラムの構造について学ぶよ。そして重要なことに、 Pythonのプログラムはクラスとオブジェクトで構成されている。 Pythonはオブジェクト指向の言語で、すべてがオブジェクトなんだ。 数字、文字列、関数、そしてクラスさえもオブジェクトだよ。
じゃあ、クラスって何だろう?
まずはアナロジーから。小さな船を作りたいと想像してみて。 まず設計図を作って、それを工場に持ち込んで、その設計図に基づいて船を組み立ててもらう。 あるいは数十隻でもいい。どれだけでも。重要なのは、1つの設計図から数十もの同じ船が作られること。
Pythonでのプログラミングも同じだよ。
設計図
プログラマーは設計者みたいなもの。設計者は設計図を書いて、Pythonプログラマーはクラスを書く。 そして設計図に基づいて部品が作られ、クラスに基づいてオブジェクトが作られる。
最初にクラスを書く(設計図を作る)、そしてプログラムが実行されるときにそのクラスに基づいてPythonがオブジェクトを作る。 ちょうど設計図に基づいて船が作られるのと同じだよ。
設計図は1つだけど、船は多く作られることがある。船は違う名前を持ち、いろいろな貨物を運ぶ。 でもとても似ているよね。同じ設計で作られていて、同様のことをこなせる。
他の例もあるよ...
蟻塚
蟻塚はオブジェクトの相互作用の良い例だよ。簡単な蟻塚には3つの種類のアリがいる:女王アリ、兵隊アリ、働きアリ。
各クラスのアリの数は異なる。女王アリは蟻塚ごとに1匹、兵隊アリは数十匹、働きアリは何百匹。 3つのクラスと何百ものオブジェクト。アリたちは固く決められたルールに従って相互に、または他のクラスのアリと相互作用する。
この例は完璧だね。典型的なプログラムでも同じだ。主要なオブジェクトが他のクラスのオブジェクトを作る。 オブジェクトは他のオブジェクトやプログラムの「外部世界」と相互作用を始める。 これらのオブジェクトの中では、その動作が厳格にプログラムされている。
これら2つの例は1枚のメダルの両面のようなものだ。真実はその中間にある。 最初の例(設計図と船)はクラスとそのクラスのオブジェクトの関係を示している。 このアナロジーは非常に強力だ。もう1つの例(蟻塚)は、プログラムの実行中に存在するオブジェクトと 記述されたクラスの関係を示している。
まず、プログラムに存在するすべてのオブジェクトのクラスを書き、その後でそれらの相互作用を記述する必要がある。 複雑に聞こえるけど、実際は思ったより簡単だよ。
Pythonでは、実行時のすべてのエンティティはオブジェクトであり、プログラムを書くことは オブジェクトのさまざまな相互作用の方法を記述することに帰結するんだ。 オブジェクトはただメソッドを呼び出して必要なデータを渡すだけ。
ドキュメンテーション
メソッドにどんなデータを渡せばいいか知りたい?それはもうすでに考えられているよ。
通常、クラスにはそのクラスが何をするためのものかという説明がある。 また、ほとんどの公開メソッドにも説明があって、何をするか、どんなデータが必要かが書かれている。
クラスを使うためには、だいたいにおいてそのクラスが何をするのか知っておく必要がある。 そしてそのメソッドが何をするのか正確に知っておく必要がある。でもどうやってするのかまでは知る必要はないんだ。 それはまるで魔法の杖。
ファイルをコピーするコードを見てみよう:
src = open('source.txt', 'r')
dst = open('destination.txt', 'w')
for line in src:
dst.write(line)
src.close()
dst.close()
このコードを1行ずつ読むと、大体何をしているのか予想できる。 でも経験と練習が必要なんだ。少し時間が経てば、このコードはおなじみの、明瞭なものに思えるだろう。
1.2. プログラムの設計
プログラムの設計は芸術のようなものと言えるよ。簡単でありながら難しくもある。 簡単なのは、厳密な法律がなく、禁止されていないことは許可されているから。 でも難しいのも同じ理由で、多くの方法があって、最適なものを見つけることが簡単ではない。
プログラムを設計するのは本を書くようなものだ。一方で、ただ文字や言葉、文を書くだけ。 でも物語やキャラクターの性格、内なる矛盾、対立、文体、サスペンスなど、色々なことが重要なんだ。
コードを書く相手を理解することが一番大事。 あなたのコードは他のプログラマー向けだということを忘れないでね。
どんな製品を開発するにしても、改良が必要なものだ:ここを加えて、ここを削除し、ここを作り直す。 こうして小さな反復を通じて大きくて巨大的なプロジェクトが生まれるんだ。
コードに対する基本的な要求は、 他のプログラマーに理解できること。 正しくなくても理解できるコードは修正できる。 正しくても理解できないコードは改善できない。ただ捨てるだけだね。
じゃあ、どうやって良いコードを書けばいいの?
そのために3つの事をすべきだよ:
- メソッド内に良いコードを書く— これが一番簡単。
- プログラムにどんなエンティティがあるべきか決定する。
- プログラムを論理的に部分に分割する。
それじゃ、これらの概念の背後にあるものは何だろう?
メソッド内に良いコードを書く
初歩的な英語の知識があれば、時々コードが文章のように簡単に読めることに気付くかもしれない:
-
class Cat(Pet)
– クラス Cat はクラス Pet を拡張する。 while stream
: – ストリームが空でない間...-
a if a < b else b
–a
がb
より小さい場合、a
を返し、そうでない場合はb
を返す。
これは意図的にそうなっているんだ。Pythonはコードを読む手間を減らすための機能がいくつか備わっている言語の1つだ。 良いPythonコードでは、コメントなしでも自然に理解できる。
コードを書くときはできるだけシンプルで簡潔にすることが重要だよ。 あなたのコードがどれだけ読みやすいかを考えて、正しい方向へ進んでいることを確認しよう。
Pythonでは読みやすいコードを書くことが求められている。 理想的には、メソッド全体が画面に収まるように(メソッドの長さは20〜30行)書くことが推奨されている。 これはPythonのコミュニティ全体の基準だよ。 コードが改善できるなら、改善すべきだ。
良いコードを書くための最良の方法は、常に練習をすること。たくさんのコードを書いて、他の人のコードを研究して、 経験のある同僚にコードレビューを依頼しよう。そして、「これでいいか」と思った時点で、あなたの成長は止まることを覚えておこう。
プログラムにどんなエンティティがあるべきか決定する
あなたのコードは他のプログラマーに理解されなければならない。プログラムを設計するときに、 10人中9人のプログラマーがクラスA、B、Cを作るなら、あなたも同じクラスを作るべきだ。 他のプログラマーが簡単に理解できるコードを書く必要があるよ。
優れた、動作する、速い、ユニークなコードは悪いコードだ。
他のプロジェクトを学ぶことが大事。それが最善の、最速の、最も簡単に情報技術の業界で蓄積された 知恵を醸成する最良の方法だよ。
幸い、あなたの近くにすでに素晴らしい、人気があり、しっかりと記載されたプロジェクトがある— Python SDK。ここから始めてみよう。
クラスやクラスの構造を解析しよう。なぜあるメソッドはstaticにされて、他のメソッドはされないのか。 なぜメソッドの引数はこうで、なぜこうではないのか。なぜこれらのメソッドが存在するのか、 なぜクラスがこう呼ばれているのか、なぜこれらのパッケージに置かれているのか。
すべての問題の答えを理解し始めると、他の人が理解できるコードを書けるようになる。
ただ、Python SDKのメソッド内のコードを解析するときは注意してほしい。 多くのメソッドが最大の速度を追求して書き直されているため、可読性は大きな疑問があるんだ。
プログラムを論理的に部分に分割する
通常、プログラムは部分的またはモジュールに分割される。それぞれの部分がプログラムの異なる側面を担当する。
例えば、コンピューターにはシステムユニット、モニター、キーボードがあって、それはすべて別個の、あまり依存しない部分だ。 さらに、それらの相互作用は標準化されている:USB、HDMIなど。 キーボードにコーヒーをこぼしても、それを洗って乾かして使い続けることができる。
しかしノートパソコンは一体型アーキテクチャの例だ:論理的な部分はあるけど、もっと統合されている。 Macbook Proなら、キーボードを掃除するためにノートパソコンを半分解体する必要がある。 ノートパソコンにコーヒーをこぼすと、新しいものを注文する理由になる。コーヒーは違うけどね。
1.3 自分のクラスを作る
プログラミングを始めたばかりの頃は、まず小さなことから始めることが大事—自分のクラスを作ることを学ぶこと。
もちろん、すでにクラスを作成しているかもしれないけど、どのクラスがプログラムにあるべきか、 どういう名前が付けられるべきか、どんなメソッドがあるべきか理解することを学ばなければならない。 そして、これらが相互にどのように作用するべきかも。
エンティティのリスト
どこから始めればよいかわからない場合は、最初から始めてみて。
プログラムの設計の初期段階で、プログラムにあるべきエンティティ(オブジェクト)のリストを紙に書き出すことができる。 その後、そのエンティティごとにクラスを作るという方法でコードを構築する。
例
例えば、チェスゲームを作りたいとしよう。必要なエンティティはチェスボードと6種類の駒だ。 駒は異なる動きをし、異なる価値を持っている—これはそれぞれ独立したクラスであることが理にかなっている。 初期段階では、多くのクラスがあるほど良い。
初心者プログラマーが2つのクラスの代わりに10個のクラスを書くのは珍しい。 逆に、10個のクラスを2つ、あるいは1つにするのは、初心者がよくやることだ。 だからもっとクラスを増やすんだ、プログラマーのみんな。そうすればみんながコードを理解しやすくなるよ。たぶん、自分以外のね 😛
チェス
チェスのクラスを書くと決めたとき、クラスはどんな形になるだろう?
チェスボードはただの8×8の配列?むしろ、それ専用のクラスを作り、その中に配列の参照を持たせるといいよ。 やっぱり「チェスボード」クラスに多くの有用なメソッドを追加することができるんだ。 例えば、マスが空いているかどうかを確認するメソッドとか。
基本的に、最初はこういう原則に従うことができる:プログラムには異なるエンティティがあり、 エンティティにはタイプがある。このタイプこそがクラスなんだ。
GO TO FULL VERSION