Pythonはオブジェクト指向のプログラミング言語です。
オブジェクト指向には《クラス》という概念があります。《クラス》は端的に言うと《設計図》です。設計図を基に家を建てるとするなら、この《家》にあたるのが《オブジェクト》です。
本稿では、Pythonでのクラス定義の方法と基本的な用語を解説します。
クラスを学ぶメリットは、日常を自然にプログラミング出来ることです。
前置きはこれくらいにしてクラスを使ったプログラムをご覧ください。
クラスを定義する
Pythonでクラスを定義するには class を使います。
以下は何もしないクラス(=空クラス)を定義する例です。
ファイル名:class_kihon0.py
# クラスの基本0: 空クラスを定義
"""
クラスAbcを定義(空クラス)
"""
class Abc:
pass
a = Abc() # クラスAbcを実体化: 変数aをクラスAbcのインスタンスと呼ぶ
※注 このプログラムは実行しても何も起きません
クラスの定義方法
クラスの定義方法は、class の後に《クラス名》: として以下に続くクラスの処理を字下げして記述します。
class 《クラス名》:
:
クラスの処理
:
関数定義のようにクラスには( ) を使って引数指定をする記述はありません。
引数は後述のメソッドやコンストラクタで利用することが出来ます。
クラス名のつけ方
クラス名は単語の先頭を大文字にして以下に続く単語があれば同じく単語の先頭を大文字(キャメルケース)にすることが推奨されています。
例えば、dogrunというクラス名を考えたとすれば、
class DogRun:
などがクラス名として適当です。
passの意味
サンプルでは空クラス(何もしない入れ物としてのクラス)を作成しています。
とりあえず入れ物としてのクラスを定義をするであればクラスの処理の部分に pass を記述します。
class Abc:
pass
passはPythonでは便利な記述です。とりあえずクラス名だけ明確だが処理はあと回し、とか関数名は決まったが処理は後で書こう、などといった時などに利用することが多いです。
インスタンス変数とインスタンス化
クラスAbcは処理を持ちませんが、設計図としては存在はしています。
この設計図をもとにクラスAbcを実体化している処理が以下の部分です。
a = Abc()
上記の場合、変数 a をクラスAbcのインスタンス変数と呼びます。変数 a はクラスAbcを実体化したものです。
実体化のイメージは、人間に例えると生まれた状態です。コンピュータではメモリ(RAM)上に領域が確保された状態を表します。人間が生まれると場所が確保されます。クラスを実体化するとコンピュータの中に存在場所が確保されるイメージです。
クラスを実体化することをインスタンス化(あるいはオブジェクト化)と呼んでいます。
Pythonでは、a = Abc() がインスタンス化している箇所です。aという変数を通してクラスAbcが実体化(=インスタンス化)したわけです。
クラスは定義しただけでは利用することが出来ません。インスタンス化して初めてコンピュータのメモリ上に存在することになります。インスタンス変数を通してプログラマはそのクラスの機能にアクセスすることが出来る様になります...って、何言ってるか分かりませんよね!では次に行きましょう!
クラスにクラス変数を定義する
実行イメージ
Pythonは1990年に誕生しました
ファイル名:class_kihon1.py
# クラスの基本1: クラス変数を定義する
class Abc:
BIRTH_YEAR = 1990 # クラス変数
print("Pythonは{}年に誕生しました".format(Abc.BIRTH_YEAR))
クラスに定義できる変数は2種類
クラスには2種類の変数を定義できます。
クラス変数とインスタンス変数です。ここではクラス変数について解説します。
クラス変数はクラスを実体化しなくても直接《クラス名》.《クラス変数名》として利用できる特殊な変数です。インスタンス変数はその逆で、インスタンス化しないと利用できません。(後述)
今回1990という整数を変数BIRTH_YEARに代入しています。
BIRTH_YEAR = 1990
これをクラス変数と呼びます。
大文字で記述していますが、小文字で birth_year としても問題なく実行できます。今回は、BIRTY_YEARはクラス変数である、という事をあえて表すために大文字で記述しています。
利用例)この場合は 1990 と表示される
print( Abc.BIRTH_YEAR)
先ほどのクラスを定義するの項で、クラスはインスタンス変数を通してクラスの機能にアクセスできる、とお伝えしたばかりなのにいきなりイレギュラーな仕様を説明することになりましたが、このクラス変数だけは特殊でクラスを実体化しなくても利用可能です。(もちろん実体化しても利用可能です)
クラスにメソッドを定義する
実行イメージ
こんにちは!
ファイル名:class_kihon2.py
# クラスの基本2: メソッドを定義する
class Abc:
# メソッドhelloを定義
def hello(self):
print("こんにちは!")
# クラスAbcをインスタンス化
a = Abc()
# クラスAbcのインスタンスaを通してクラスAbcのメソッドhelloを呼び出す
a.hello()
メソッドとは?
メソッドとは、クラスの持つ振る舞い(動作)です。
メソッドは以下の定義部分です。
class Abc:
# メソッドhelloを定義
def hello(self):
print("こんにちは!")
定義方法は、関数定義とほぼ同じです。
字下げしてクラス内部にdef 《メソッド名》として記述したものがそのクラスのメソッド(振る舞い)となります。
メソッドの定義にはselfが必要
メソッド定義部分に注目してください。
selfという見慣れない記述があります。
def hello(self):
関数定義であればこの部分は引数となりますが、メソッド定義の場合実際に利用する引数はself以降に記述する形となります。
例)def sub(self, x, y, z…) :
※この場合、x, y, z がそれぞれメソッドsubの引数となる
selfとはインスタンスのこと
メソッド引数の先頭に記述する self とは、自分自身すなわちインスタンスの事を表します。
実際はdef sub(watasi, x, y, z…): などと self 以外の名前を使っても問題ないのですが、Pythonのメソッドでは慣例としてselfを使うのが分かりやすさの点からも無難でしょう。(このサイトでも self で統一して記述させて頂きます)
メソッドを定義する場合、引数に最低限 self は必要と覚えておいてください。
メソッドの呼び出し方法
メソッドは、インスタンス変数.メソッド名()の形で呼び出す事が出来ます。
サンプルでは a = Abc() としてクラスAbcを変数 a にインスタンス化しているため、インスタンス変数 a を使って
a.hello()
として呼び出して利用しています。
引数を利用したメソッドの例
selfだけではピンとこないので、引数を実際に利用したメソッド例をみてください。
実行イメージ
こんにちはレナさん!
こんにちは圭一さん!
ファイル名:class_kihon3.py
# クラスの基本3: 引数を持つメソッドを定義する
class Abc:
# メソッドhelloを定義
def hello(self, name): # メソッドhelloは引数nameを持つ
print("こんにちは{}さん!".format(name))
# クラスAbcをインスタンス化
a = Abc()
# クラスAbcのメソッドhelloを呼び出す(呼び出し時に引数が必要)
a.hello("レナ")
a.hello("圭一")
selfの次に記述した第2引数(この場合はname)が実際にメソッドを呼び出すときの引数となります。
クラスに定義したメソッドの引数は呼び出すときにselfを差し引いた引数にする必要があります。
例)
メソッド定義例 | メソッドの呼び出し例 |
def hoge(self, x, y): | a.hoge(10, 20) |
コンストラクタは自動実行するメソッド
コンストラクタとは、クラスをインスタンス化したときに自動的に実行される特殊なメソッドの事です。
サンプルをご覧ください。
実行イメージ
コンストラクタを実行したよ!
ファイル名:class_kihon4.py
# クラスの基本4: コンストラクタを定義する
class Abc:
# コンストラクタを定義
def __init__(self):
print("コンストラクタを実行したよ!")
# クラスAbcをインスタンス化
a = Abc() # この時点でコンストラクタが実行される
def __init__(self): 以下に定義された処理をコンストラクタと呼びます。
# コンストラクタの定義
def __init__(self):
:
《コンストラクタの処理》
:
※ちなみにinitの前後のアンダーバー _ はそれぞれ2つずつです。
コンストラクタに記述された処理は、クラスをインスタンス化した時点で実行されます。
print("コンストラクタを実行したよ!")
の部分は、 a = Abc() が実行された時点で自動的に実行されています。
コンストラクタは呼び出す必要のないメソッドと言えます。
コンストラクタの利用例
以下はコンストラクタに引数を定義した利用例です。
クラスを引数付きでインスタンス化することが出来ます。
実行イメージ
ようこそSOS団へ!
ようこそ雛見沢へ!
ファイル名:class_kihon5.py
# クラスの基本5: コンストラクタにも引数が設定できる
class Abc:
# コンストラクタを定義(引数有り)
def __init__(self, area):
print("ようこそ{}へ!".format(area))
# クラスAbcをインスタンス化
a = Abc("SOS団") # この時点でコンストラクタが実行される
a = Abc("雛見沢") # この時点でコンストラクタが実行される
インスタンス変数を使う
クラスにはインスタンス化無しで利用できるクラス変数(前述)とインスタンス化したときに利用可能なインスタンス変数があります。ここではインスタンス変数について解説します。
実行イメージ
Pythonは1990年オランダで産声を上げた
ファイル名:class_kihon6.py
# クラスの基本6: インスタンス変数を宣言する
class Abc:
# コンストラクタを定義
def __init__(self):
self.year = 1990 # インスタンス変数
self.country = "オランダ" # インスタンス変数
# メソッドでインスタンス変数を表示する
def showInformation(self):
print("Pythonは{}年{}で産声を上げた".format(self.year, self.country))
# クラスAbcをインスタンス化
a = Abc()
# メソッドを実行
a.showInformation()
インスタンス変数の定義方法
インスタンス変数はコンストラクタ内に記述します。
変数名の頭にself.をつけて定義します。
class Abc:
# コンストラクタを定義
def __init__(self):
self.year = 1990 # インスタンス変数
self.country = "オランダ" # インスタンス変数
:
インスタンス変数の利用方法
インスタンス変数はクラス内部ではself.をつけて利用します。
print("Pythonは{}年{}で産声を上げた".format(self.year, self.country))
クラスの外部ではselfの代わりに《インスタンス.インスタンス変数名》として利用できます。
ファイル名:class_kihon7.py
# クラスの基本7: インスタンス変数を外部から利用する
class Xyz:
# コンストラクタを定義
def __init__(self):
self.favorite = "トマト" # インスタンス変数
# クラスXyzをインスタンス化
a = Xyz()
# インスタンス変数利用
print("{}は美味しい".format(a.favorite))
実行イメージ
トマトは美味しい
上記例ではクラスXyzのインスタンスaを通してインスタンス変数を利用しています。
print("{}は美味しい".format(a.favorite))
クラスを使ってRPGのキャラクタを表現してみる
ここまで学んだクラスの要素を使ってRPGのキャラクタをクラス Character として表現してみました。
プログラムの流れを追ってみてください。
ファイル名:class_character.py
# クラスの基本7: RPGのキャラクタをクラスで表現してみる
import random
"""
クラスCharacterを定義
"""
class Character:
# コンストラクタ: キャラの初期設定
def __init__(self, name, hp, power):
self.name = name
self.hp = hp
self.power = power
print("{}が現れた!体力:{} 攻撃力:{}".format(self.name, self.hp, self.power))
print()
# メソッド: キャラの攻撃
def command(self):
print("{}の攻撃!".format(self.name))
print("{}のダメージを与えた".format(random.randint(1, self.power)))
print()
# キャラを生成
slime = Character("スライム", 3, 5)
slime_bess = Character("スライムベス", 4, 7)
# キャラのコマンドを表示
slime.command()
slime_bess.command()
実行イメージ(乱数を利用している為、実行する度に数値は変化します)
スライムが現れた!体力:3 攻撃力:5 スライムベスが現れた!体力:4 攻撃力:7 スライムの攻撃! 4のダメージを与えた スライムベスの攻撃! 4のダメージを与えた
以上、Python:クラスの定義方法と基本的な用語解説でした。
オブジェクト指向への道のりは今始まったばかりです!
コメント