【Python入門】オブジェクト指向プログラミング

このページでは、Pythonでオブジェクト指向プログラミングをする方法について入門者向けに解説しています。

【はじめに】オブジェクト指向プログラミングとは

オブジェクト指向とは、関連するデータのやそれに対する処理を「オブジェクト」と呼ばれる1つのまとまりで管理する考え方です。
この考え方に沿ってプログラミングすることを「オブジェクト指向」プログラミングといいます。

オブジェクト 関連するデータや処理を1つにまとめたモノ。
指向 ある方向・目的に向かうことです。(オブジェクト指向なら、オブジェクトの考え方に重きを置くこと)

例えば、パソコンをオブジェクトとして考えてみます。
コンピュータ内部のアルゴリズムや電気的な仕組みを理解しなくても、マウスやキーボードの使い方だけを知っていればパソコンを使うことができます。
「パソコン」というオブジェクトは、自身を動作させるための処理を知っています。
それを利用するためには、キーボードやマウスで指示すれば良いです。
このように「データ」と「操作するための処理(メソッド)」を組み合わせが「オブジェクト」です。

オブジェクト指向でプログラムを設計するメリット
1 大規模なプログラムを書きやすい
2 プログラムの柔軟性が高い(仕様変更・再利用しやすい)
3 綺麗に書けば理解しやすいプログラムを書ける
オブジェクト指向でプログラムを設計するデメリット
1 プログラム設計に時間が掛かりやすい
2 プログラムの処理時間が長くなる
3 綺麗に書かないと理解しにくいプログラムになる

一般的にオブジェクト指向プログラミングは大規模なプログラムを作る場合に向いているとされています。
逆に小規模なプログラムの場合は、関数型で設計するのが向いています。
難しいのはその境目をどこに置くかとなります。

用語 オブジェクト指向の用語概要
クラス オブジェクト指向プログラミングにおけるクラス (class)とは、オブジェクトの設計図です。オブジェクトがどのようなデータや操作(手続き)の集まりかを決める雛形(テンプレート)ともいえます。オブジェクトを作る際には、必ずクラス(設計図)を定義する必要があります。
インスタンス 実体という意味です。クラス(設計図)を元にして実際に作った物がインスタンス(実体)です。
メソッド(操作) オブジェクト自身に対する操作のことです。オブジェクトは「データ」と「手続き」から構成されており、手続き(method)の部分がメソッドに相当します。別名、メンバ関数とも呼ばれます。
プロパティ(属性) オブジェクト固有のデータです。オブジェクトの性質や設定に関する情報となります。
クラス変数 そのクラスの全てのインスタンスで共有される変数です。グローバル変数(ファイル内全体)のクラス版のようなものです。クラス変数は何度でも値を変更できます。また、クラス変数はクラスメソッド、インスタンスメソッド、クラス定義式の中でアクセス可能です。
インスタンス変数 オブジェクトのインスタンス(実体)がそれぞれに持っている変数です。オブジェクト内で値を保存しておくために利用されます。

オブジェクトは物、クラスはオブジェクトの設計図、インスタンスはオブジェクトの実体です。
車で例えると以下のようになります。

オブジェクト・クラス・インスタンスの違い(車の設計で例えると)
オブジェクト
クラス 車の設計図(どのようなパーツで構成されてどのように動くか記述されている)
インスタンス 完成車(設計図を元に実際に作って完成した車)
詳細ページ
1 オブジェクト指向プログラミングとは(概念・対応言語など)
2 オブジェクト指向のメリット・デメリット
3 クラス・インスタンスとは?意味や違いを解説
4 メソッド・プロパティとは?意味、違い、使い分け
5 クラス変数・インスタンス変数とは?意味、違い、使い分け

【クラス】class文で定義

Pythonでは、class文を用いてクラスを定義します。
class文でクラス定義する書式は下記の通りです。

# クラスの定義
class MyClass(object):
    pass

クラス定義の範囲はコロン「:」の後にインデントをつけることで設定できます。
また、クラス名(MyClass)は頭文字を大文字で始めるのが慣習となっています。
上記のように要素(データやメソッド)を持たないクラスを定義する場合はインデントして「pass」だけ書きます。

関連記事
1 【Python】クラスの定義 (class文)

【インスタンス】生成、個数の計算、暗黙的に文字列に変換

Pythonでインスタンス生成する書式は下記の通りです。

# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    pass

# インスタンスの生成
my = MyClass()

※変数がインスタンス(実体)となります。
(クラスは設計図)

関連記事
1 【Python】インスタンスの生成

インスタンスの個数は次のコードで求まります。
コンストラクタについては後述します。

# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    n = 0
    # コンストラクタ(初期化メソッド)
    def __init__(self):
        MyClass.n += 1

# インスタンスを2つ生成
my1 = MyClass()
my2 = MyClass()

# インストラクタ変数の数を表示
print(MyClass.n) # 2
関連記事
1 【Python】インスタンスの個数を求める

Pythonでインスタンスを暗黙的に文字列に変換するには、「str()」を用います。

class MyClass:
    def __init__(self, src):
        self.src = src

    def __str__(self):
        return "Hello " + self.src


my = MyClass("Yamada")

print(my) # Hello Takashi
関連記事
1 【Python】インスタンスを暗黙的に文字列に変換 str()

【インスタンス変数】生成、値取得、代入・アクセス、追加、生成時の値渡し

インスタンス変数とは、生成されたインスタンス内のみで使える変数です。
Python言語のインスタンス変数の宣言は「self.インスタンス変数 = 値」で記述します。下記の通りです。

# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    def __init__(self):
        self.x = 10     # インスタンス変数x
        self.y = 20     # インスタンス変数y
        self.z = self.x + self.y


# インスタンスの生成
my = MyClass()

# インスタンス変数の中身を表示
print(my.z)

インスタンス変数を生成する場合は、クラス内のメソッド(一般的にはコンストラクタ:init()の中)で次のように書きます。

関連記事
1 【Python】インスタンス変数の生成(宣言と定義)

インスタンス変数の値を取得するには「変数 = インスタンス.インスタンス変数」を用います。

# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    # コンストラクタ
    def __init__(self):
        # インスタンス変数の宣言・初期化
        self.x = 10
        self.y = 20
        self.z = self.x + self.y


# インスタンスの生成
my = MyClass()

# インスタンス変数の値を取得
z = my.z 

# インスタンス変数の中身を表示
print(z) # 30
関連記事
1 【Python】インスタンス変数の値取得

インスタンス変数へ外部から代入・アクセスする書式は下記の通りです。

書式
外部(クラス外)から代入 インスタンス.インスタンス変数 = 値
内部(クラス内)から代入 self.インスタンス変数 = 値
# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    def __init__(self):
        self.x = 0     # インスタンス変数xへ内部から値を代入
        self.y = 0     # インスタンス変数yへ内部から値を代入
        self.z = self.x + self.y


# インスタンスの生成
my = MyClass()

# インスタンス変数へ外部から値を代入
my.x = 10
my.y = 20
my.z = my.x + my.y

# インスタンス変数の中身を表示
print(my.z) # 30
関連記事
1 【Python】インスタンス変数に代入・アクセス

Python言語のインスタンス変数は、インスタンス変数への代入を行った時、そのインスタンス変数がクラス文で定義されていなかった場合にインスタンス内に自動的に追加してくれます。
これは他のプログラミング言語にはあまりない特徴です。

# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    pass


# インスタンスの生成
my = MyClass()

# インスタンス変数の生成
my.x = 10
my.y = 20
my.z = my.x + my.y

# インスタンス変数の中身を表示
print(my.z) # 30

クラス文内でインスタンス変数x, y, zを定義していなくても外部から追加してアクセスできることがわかります。

関連記事
1 【Python】インスタンス変数の追加

インスタンスの生成時にインスタンス変数に値をセット(初期化)できます。

# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    # コンストラクタ(インスタンス生成時に自動で呼び出される)
    def __init__(self, x, y): # 初期化
        # インスタンス変数の宣言・初期化
        self.x = x
        self.y = y
        self.z = self.x + self.y


# インスタンスの生成(同時にインスタンス変数を初期化)
my = MyClass(10, 20)

# インスタンス変数の中身を表示
print(my.z) # 30

インスタンス変数は一般的にクラス文のコンストラクタ initの中で初期化します。
(メソッド内でもできる)

関連記事
1 【Python】インスタンス生成時に値を渡す(初期化)

【クラス変数】定義、値取得、代入、追加(自動生成)

クラス変数とは、クラス全体で共通の変数です。
インスタンス変数とは違い、生成された全てのインスタンス間で共通した値を持ちます。
クラス変数はインスタンスを生成せずに参照できます。

# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    x = 10

※クラス文の”直下”に記述します。

関連記事
1 【Python】クラス変数の定義(宣言・初期化)

次にクラス変数の値を取得してみます。

# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    x = 10


# クラス変数の値を取得
x = MyClass.x

# クラス変数の中身を表示
print(x) # 10

■書式
変数 = クラス.クラス変数

関連記事
1 【Python】クラス変数の値を取得
# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    x = 10

# クラス変数に値を代入
MyClass.x = 20

# クラス変数の中身を表示
print(MyClass.x) # 20

■書式
クラス.クラス変数 = 値

関連記事
1 【Python】クラス変数に値を代入

Python言語のクラス変数は、クラス変数への代入を行った時、クラス文で定義されていなかった場合に自動的に生成してくれます。
これによりクラス変数を外部から追加することができます
これは他のプログラミング言語にはあまりない特徴です。

# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    x = 10

# クラス変数を追加
MyClass.y = 20

# クラス変数の中身を表示
print(MyClass.y) # 20

クラス文内でクラス変数yを定義していなくても外部から追加してアクセスできることがわかります。

関連記事
1 【Python】クラス変数の追加

【メソッド】初期化、クラスメソッド、コンストラクタ、デストラクタ

メソッド(method)とは、クラスが持つ関数のことです。
メソッドには操作・処理の内容を記述します。

# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    # メソッド
    def calc(self, x, y):
        self.z = x + y

# インスタンスを生成
my = MyClass()

# メソッドcalcに(x=10, y=20)を渡す
my.calc(10, 20)

# インストラクタ変数zを表示
print(my.z) # 30

メソッドはclass文の中で定義します。
メソッドの第1引数にはインスタンスが渡されます。
この引数名は「self」と記述します。

関連記事
1 【Python】メソッドの定義・引数に値を渡す

クラスメソッドとは、クラスの動作を決めるメソッドです。
インスタンス化しなくても呼び出すことができます。
Pythonではクラスメソッドの実装にはデコレータ(@classmethod)を使います。

# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    @classmethod
    # クラスメソッド
    def calc(self, text):
        print(text)

# クラスメソッドの呼び出し
MyClass.calc("Nyan Pass!") # Nyan Pass!
関連記事
1 【Python】クラスメソッドの定義

クラスを定義する場合、そのクラスのインストラクタが生成されるときに呼び出される「初期化メソッド」を定義できます。
これを「コンストラクタ」といいます。

Python言語では、「def init(self, src1, src2, …):」という風にしてコンストラクタを記述します。

# -*- coding: utf-8 -*-

# クラスの定義
class MyClass():
    # コンストラクタ(初期化メソッド)
    def __init__(self, text):
        self.text = text

# コンストラクタでインスタンス変数を初期化
my = MyClass("Nyan Pass!")

# インスタンス変数を表示
print(my.text) # Nyan Pass!

クラス文内でクラス変数yを定義していなくても外部から追加してアクセスできることがわかります。

おすすめ関連記事
1 【Python】コンストラクタ・初期化メソッド

【クラス継承】スーパークラス・サブクラス

クラスの継承とは、既に定義しているクラスの機能を流用し、新しいクラスを作成することです。
継承元のクラスを「スーパークラス」、それを用いて新しく作成するクラスを「サブクラス」と言います。
これをうまく使うことでコードの記述量を減らすことが出来ます。

【書式】class サブクラス名(スーパークラス名):

# -*- coding: utf-8 -*-

# スーパークラスの定義
class MyClass1:
    # コンストラクタ(初期化メソッド)
    def __init__(self, x, y):
        self.x = x
        self.y = y


# サブクラスの定義
class SubClass(MyClass1):
    # メソッド(追加分)
    def dot(self):
        self.z = self.x * self.y
        return self.z

# サブクラスのインストラクタを生成
mysub = SubClass(10, 20)

print( mysub.dot() ) # 200
関連記事
1 【Python】クラス継承 (スーパークラス・サブクラス)

【自作モジュール】作成・読み込み

Python言語で自作ライブラリ・モジュールを読み込んで使う際の手順は以下の通りです。

①「自作モジュールのファイル名」を「モジュール名」にする。
②モジュールを呼び出す際は、「import モジュール名」で行う。
③「モジュール名.クラス名」でモジュールのクラスを呼び出す。
※モジュール名の記述を省略したい場合は、「from モジュール名 import クラス名」でモジュールを呼び出す。

モジュール側(my.py)

# -*- coding: utf-8 -*-
class MyClass:

    def __init__(self):
        print("初期化")

    def my_method(self, message):
        print("Test", message)

This Gist brought to you by gist-it. view raw Python/Module/My/my.py

呼び出す側(main.py)

# -*- coding: utf-8 -*-
import my # 自作モジュールのインポート

# インスタンスの生成
my_class = my.MyClass()

# メソッドの呼び出し
my_class.my_method("にゃんぱすー")

"""
実行結果
---------
初期化
TESTにゃんぱすー
"""
関連記事
1 【Python】自作ライブラリ・モジュールの読み込み
関連記事
1 Pythonでオブジェクト指向プログラミング
2 Python入門 基本文法
関連記事