【Pythonを使い倒す】まだオブジェクト指向で悩んでない?オブジェクトとメソッドの書き方を覚えて洗練されたコードを書けるあなたになろう

共通の処理を外部化したり、外部のライブラリを使用できるモジュールについて解説をしました。今回はオブジェクト指向を解説します。

オブジェクト指向の考え方とは

オブジェクト指向は、オブジェクトと呼ばれるものをベースにしています。
オブジェクトは、配列や関数と同じように基本的には「複数のデータをまとめて一つの変数で管理する」データの種類のことです。

オブジェクト指向は、オブジェクト同士の相互作用として、プログラムの振る舞いをとらえる考え方なので、何かを実行させたいときは「○○は××しなさい」と命令する書き方をします。

  • 「○○は」にあたる部分をオブジェクト
  • 「××しなさい」にあたる部分をメソッド

メソッドはオブジェクトで実行させたい指示
指示対象がオブジェクトであることに対し、指示内容がメソッドとなります

例えば、「たまご」がオブジェクトとした場合、

「焼くことで、たまご焼きという結果を出しなさい」「ゆでることで、ゆでたまごという結果を出しなさい」といったところが、メソッドとなります。

つまり、オブジェクトには、それぞれ固有のメソッドを持っています。

オブジェクト指向には、オブジェクトの他に、クラスとインスタンスという概念があります。
クラスは設計図のようなもので、クラスを実体化(インスタンス化)したものがインスタンスです。
オブジェクトは、クラスとインスタンスの総称です。

オブジェクトの書き方

以下の例では、クラスからインスタンスを生成しています。
classの表記の後に、クラス名を記述します。
クラスは、メソッドという関数のようなものを含むことができます。
メソッドは、( )内にselfと書きますが、この意味については後に解説します。

オブジェクトの書き方
class Jobs: # クラス 設計図のようなもの
def sayApple(self): # メソッド 関数に似ている
print("Apple!")

p = Jobs() # クラスからインスタンスを生成、pがインスタンス
p.sayApple() # メソッドの呼び出し
実行結果

Apple!

こちらの例のコードではまずclassと書いてその後にJobsというクラス名が書いてあります。
繰り返しになりますがクラスとは設計図のようなものです。

このクラスの中にsayApple()というメソッドが記述してあります。

メソッドは関数に似ており、最初にdefと書いて、その後に任意のメソッド名を定義します。
メゾットの場合、括弧()の中にselfと書きます

このsayApple()メソッドは”Apple!”とプリントするだけのシンプルなメソッドです。
クラス名の後に、括弧()をつけることでクラスからインスタンスを生成することができます。

この場合、生成したインスタンスは変数pに代入しています。

そして、このインスタンスからsayApple()メソッドを呼び出します。

実行すると、sayApple()メソッドが呼び出されて”Apple!”とプリントされました。
今回はクラスのシンプルな例を書きましたがクラスを用いてより複雑で機能的なコードを書くことができます。

今回のサンプルの記述内で行われた実装手順をおさらいで以下のステップでまとめました。

  1. 好きな名前のクラスを記述
  2. クラスの中に適当な文字列をプリントするメソッドを記述
  3. クラスからインスタンスを生成
  4. インスタンスからメソッドを呼び出す。

クラスの書き方に少しずつ慣れていきましょう。

配列ってもしかしてオブジェクト?

と、勘のいい方はすでにお気づきかもしれません。
そうです。配列はオブジェクトです。
オブジェクトということは、メソッドがあります。配列には配列を操作するためのメソッドが用意されているのです。

プログラムを書きながら少し説明しましたが、オブジェクトとは、「複数の変数や関数を持つデータのまとまり」です。
それぞれの変数や関数にデータが保存されているので、オブジェクトとは「各種のデータをひとまとめにして、1つの変数として扱えるデータ」ということもできるでしょう。

どちらを選べばいいの? 配列vsオブジェクト

配列とオブジェクトは、どちらも複数のデータを1つにまとめるために使うデータです。

どうやって使い分けるのでしょうか?
それぞれに何か特徴があるのでしょうか?
配列とオブジェクトは持っている機能が違うため、データを処理する際にどちらが向いているかを考えて決めるのですが、そういうことを判断するには多少なりとも経験が必要です。

経験がなくても選びやすい分類方法

そこで、イメージしやすい方法を紹介します。
皆さんは、Excelなどの表計算ソフトを使ったことがあると思います。
あるデータをPythonで使うときに、そのデータをもし表計算送付に入力するとして、「そのデータは縦に並べて入力したくなるか?それとも横か?」と、想像してみてください。

縦に並べたくなるようなデータであれば配列向き

1北海道
2青森
・・・
47沖縄

縦に並べて入力したくなるようなものであれば、配列が向いています。
たとえば「やることリスト」は、通常は縦方向に並べると思います。
横方向ではありませんね。
そのほかに思いつくものとして、縦方向に並べたくなるデータには次のようなものが挙げられるでしょう。

  • 都道府県
  • 持ち物リスト
  • 学校のクラスの名簿

横に並べたくなるようなデータはオブジェクト向き

userscorenation
HARU99999999JP

一方、そのデータが横に並べたくなるようなものであれば、オブジェクトが向いています。
たとえば、次のような「1つの何か」に紐づく複数のデータを管理するのは、オブジェクトのほうが向いています。

  • ゲームのハイスコアデータ(プレイヤー名と点数)
  • パソコンやスマートフォンなどの電化製品のスペック(サイズ、速度など)
  • ある商品の価格の在庫数

縦横に広がる表

ところで、「やることリスト」は縦に並べたくなるデータなので、配列が向いているといいました。
ここでもし、「やることリスト」の各項目に、

  • 期限
  • 優先順位

などの情報を追加するとしたら、表計算ソフトではやることリストの横に並べて入力するでしょう。
そうすると、縦横に広がる表になります。

やることリストに情報を追加すると

tododuepriority
デザイン11月20日1
飛行機手配11月22日3
本返す12月1日2

このようなデータを管理する場合、Pythonでは、と、配列とオブジェクトを組み合わせて管理します。

メソッド

メソッドの書き方

続いて、メソッドを解説します。

クラスの中にはメソッドを実装することができます。
メソッドは関数に似ていますが、活用することで多様な機能をクラスに持たせることができます。

クラスからインスタンスを生成し、インスタンスからメソッドを呼び出すことができます。

以下の例はシンプルなメソッドの例です。
クラスGreetingには、sayHelloメソッドが実装されています。
このクラスからインスタンスを生成し、インスタンスからsayHelloメソッドを呼び出しています。

こちらの例を見ていきましょう。

メソッドの書き方
class Greeting1:
def sayHello(self): # メソッド
print("Hello!")

gr_1 = Greeting1() # インスタンスの生成
gr_1.sayHello() # メソッドの呼び出し
実行結果

Hello!

クラスGreeting1にはsayHello()メソッドが実装されています。
メソッドなので括弧の中にはselfが入ります。
このメソッドは”Hello!”とプリントするだけのシンプルなメソッドです。

クラスGreeting1からインスタンスを生成しgr_1という名前の変数に格納します。
そしてこのインスタンスからsayHello()メソッドを呼び出します。

実行すると、インスタンスからsayHello()メソッドが呼び出されて”Hello!”とプリントされました。
このようにインタンスからメソッドが呼び出されますが、selfはそのインスタンス自身を表します。
インスタンスからはメソッドを呼び出すことができるので、selfを用いてメソッドの中からでも他のメソッドを呼び出すことができます。

selfを用いて他のメソッドを呼び出す

以下の例では、selfを用いて他のメソッドを呼び出しています。

selfを用いて他のメソッドを呼び出す
class Greeting2:
def sayNice(self):
self.sayHello() # selfはインスタンス自身 インスタンスから他のメソッドを呼び出す
print("Nice to meet you!")

def sayHello(self):
print("Hello!")

gr_2 = Greeting2()
gr_2.sayNice()

実行結果

Hello!
Nice to meet you!

Greeting2というクラスがあって、その中にsayNice()とsayHello()という2つのメソッドが実装されています。
sayHello()の方は”Hello!”とプリントするだけのメソッドです。
それに対してsayNice()はselfを使ってsayHello()メソッドを呼び出しています。

このselfはインスタンス自身なのでインスタンスから他のメソッドを呼び出すことになります。
そしてその後に”Nice to meet you!”とプリントします。

このGreeting2クラスからインスタンスを生成してgr_2という変数に格納してsayNice()メソッドを呼び出します。

実行するとsayNice()メソッドからsayHello()メソッドが呼び出されて”Hello!”とプリントされて、その後に”Nice to meet you!”とプリントされました。
このようにselfを用いてメソッドからメソッドを呼び出すことができます。

のちの記事でクラスから直接呼び出す”クラスメソッド”というものを扱います。
しかしながら、今はとりあえず「インスタンスからメソッドを呼び出す」と認識しておいてください。

今回のサンプルの記述内で行われた実装手順をおさらいで以下のステップでまとめました。

  1. クラスを記述しその中にメソッドを一つ記述
  2. メソッドをもう一つ追加し、片方のメソッドからもう片方のメソッドを呼び出す。
  3. クラスからインスタンスを生成しメソッドを呼び出す。

メソッドのコードを実際に書いてその扱い方に慣れていきましょう。

今回はオブジェクト指向とオブジェクトとメソッドの書き方を解説しました。
活用することで洗練されたコードを書けるようになりますので何度もコードを書いて練習しておきましょう。