Pythonにおけるオブジェクト指向プログラミングについて入門者向けに解説しています。
オブジェクト指向の概要
オブジェクト指向は、データとその操作を一つの「オブジェクト」としてまとめるプログラミングの考え方です。これにより、コードの再利用性や拡張性が向上します。この考え方に沿ってプログラミングを行うことを、「オブジェクト指向プログラミング」といいます。
オブジェクト指向の基本要素となる「オブジェクト」「クラス」「インスタンス」「属性」「メソッド」について表にまとめると以下のとおりです。
項目 | 説明 | 例 |
---|---|---|
オブジェクト | データとそのデータを操作するメソッドを持つ独立したものです。 | ー |
クラス | オブジェクトの設計図のようなものです。クラスには、オブジェクトが持つ属性(データ)とメソッド(操作)を定義します。つまり、クラスという設計図を基にして、具体的なオブジェクト(インスタンス)を作成します。 | RPGゲームだと、キャラクターを作成するためのクラスを作成します。このクラスには、キャラクターの属性(名前、レベル、体力など)やメソッド(攻撃、回復、移動など)が定義されます。 |
インスタンス | クラスから生成された具体的なオブジェクトのことです。クラスという設計図から生成された具体的なオブジェクトがインスタンスです。 | RPGゲームだと、キャラクター作成用クラスから「勇者」オブジェクトという具体的なキャラクター(インスタンス)を生成します。 |
属性 | オブジェクトが持つデータのことです。 | RPGゲームだと、例えばキャラクターの名前、レベル、体力、魔力などが属性となります。 |
メソッド | クラスが持つ関数のことです。つまり、オブジェクトに対して行う操作や処理の内容が記述されます。 | RPGゲームだと、キャラクターに対して行う操作(攻撃する、回復する、移動するなど)がメソッドとなります。 |
カプセル化 | キャラクターの内部状態(属性)を外部から直接アクセスできないようにする概念です。これにより、データの保護や操作の一貫性が保たれます。 | ー |
継承 | 既存のクラス(親クラス)を基に新しいクラス(子クラス)を作成する方法です。 | RPGゲームだと、基本的なキャラクタークラスを親クラスとし、特定の種類のキャラクター(例えば、戦士や魔法使い)を子クラスとして作成できます。 |
ポリモーフィズム | 同じメソッド名が異なるクラスで異なる動作をすることを指します。 | RPGゲームだと、例えば、戦士と魔法使いで異なる攻撃方法を持つことができます。 |
クラスの定義(class文)
Pythonでは、class文を用いてクラスを定義します。
class文でクラス定義する書式は下記の通りです。
# クラスの定義 class MyClass(object): pass
クラス定義の範囲はコロン「:」の後にインデントをつけることで設定できます。
また、クラス名(MyClass)は頭文字を大文字で始めるのが慣習となっています。
上記のように要素(データやメソッド)を持たないクラスを定義する場合はインデントして「pass」だけ書きます。
https://python.joho.info/programming/python-class/
インスタンスの生成
Pythonでインスタンス生成する書式は下記の通りです。
# -*- coding: utf-8 -*- # クラスの定義 class MyClass(): pass # インスタンスの生成 my = MyClass()
※変数がインスタンス(実体)となります。
(クラスは設計図)
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
インスタンスの個数は次のコードで求まります。
コンストラクタについては後述します。
# -*- coding: utf-8 -*- # クラスの定義 class MyClass(): n = 0 # コンストラクタ(初期化メソッド) def __init__(self): MyClass.n += 1 # インスタンスを2つ生成 my1 = MyClass() my2 = MyClass() # インスタンス変数の中身を表示 print(MyClass.n) # 2
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
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
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
インスタンス変数の操作
インスタンス変数とは、生成されたインスタンス内のみで使える変数です。
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()の中)で次のように書きます。
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
インスタンス変数の値を取得するには「変数 = インスタンス.インスタンス変数」を用います。
# -*- 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
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
インスタンス変数へ外部から代入・アクセスする書式は下記の通りです。
– | 書式 |
---|---|
外部(クラス外)から代入 | インスタンス.インスタンス変数 = 値 |
内部(クラス内)から代入 | 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
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
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を定義していなくても外部から追加してアクセスできることがわかります。
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
インスタンスの生成時にインスタンス変数に値をセット(初期化)できます。
# -*- 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の中で初期化します。
(メソッド内でもできる)
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
クラス変数の操作
クラス変数とは、クラス全体で共通の変数です。
インスタンス変数とは違い、生成された全てのインスタンス間で共通した値を持ちます。
クラス変数はインスタンスを生成せずに参照できます。
# -*- coding: utf-8 -*- # クラスの定義 class MyClass(): x = 10
※クラス文の”直下”に記述します。
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
次にクラス変数の値を取得してみます。
# -*- coding: utf-8 -*- # クラスの定義 class MyClass(): x = 10 # クラス変数の値を取得 x = MyClass.x # クラス変数の中身を表示 print(x) # 10
■書式
変数 = クラス.クラス変数
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
# -*- coding: utf-8 -*- # クラスの定義 class MyClass(): x = 10 # クラス変数に値を代入 MyClass.x = 20 # クラス変数の中身を表示 print(MyClass.x) # 20
■書式
クラス.クラス変数 = 値
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
Python言語のクラス変数は、クラス変数への代入を行った時、クラス文で定義されていなかった場合に自動的に生成してくれます。
これによりクラス変数を外部から追加することができます
これは他のプログラミング言語にはあまりない特徴です。
# -*- coding: utf-8 -*- # クラスの定義 class MyClass(): x = 10 # クラス変数を追加 MyClass.y = 20 # クラス変数の中身を表示 print(MyClass.y) # 20
クラス文内でクラス変数yを定義していなくても外部から追加してアクセスできることがわかります。
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
メソッドの定義と操作
メソッド(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」と記述します。
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
クラスメソッドとは、クラスの動作を決めるメソッドです。
インスタンス化しなくても呼び出すことができます。
Pythonではクラスメソッドの実装にはデコレータ(@classmethod)を使います。
# -*- coding: utf-8 -*- # クラスの定義 class MyClass(): @classmethod # クラスメソッド def calc(self, text): print(text) # クラスメソッドの呼び出し MyClass.calc("Nyan Pass!") # Nyan Pass!
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
クラスを定義する場合、そのクラスのインストラクタが生成されるときに呼び出される「初期化メソッド」を定義できます。
これを「コンストラクタ」といいます。
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を定義していなくても外部から追加してアクセスできることがわかります。
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
クラス継承(スーパークラス・サブクラス)
クラスの継承とは、既に定義しているクラスの機能を流用し、新しいクラスを作成することです。
継承元のクラスを「スーパークラス」、それを用いて新しく作成するクラスを「サブクラス」と言います。
これをうまく使うことでコードの記述量を減らすことが出来ます。
【書式】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
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
自作モジュールの作成・読み込み
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にゃんぱすー """
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
関連ページ
![](https://algorithm.joho.info/wp-content/uploads/2023/08/404-160x90.jpg)
コメント
勉強させて頂いております。
# インストラクタ変数の数を表示
↑↑↑↑↑↑↑
ご指摘ありがとうございます!(*^^*)