4.1 初期化
通常、オブジェクトを作成した直後はまだ準備ができていないことが多いよね。まず、その中にすべての必要なデータを渡す必要があるんだ: 作業パラメータ、初期値、他のオブジェクトへの参照など。
このプロセスは初期化って呼ばれて、オブジェクトを作成した直後に行われるべきだよ。
例えば、クラスCatがあって、その名前と年齢を設定したいとする。この方法はいくつかあるよ:
オブジェクト作成後の属性の初期化
この例では、まず次が作成される:
- 空のオブジェクト
Cat。 - クラス
Catのインスタンスで、名前がbarsik。 - その後、オブジェクトbarsikに2つの属性、
nameとage、これが直接オブジェクトに追加される。
class Cat:
pass
# Catオブジェクトの作成
barsik = Cat()
# オブジェクト作成後の属性の初期化
barsik.name = "Barsik"
barsik.age = 5
print(f"猫の名前: {barsik.name}, 年齢: {barsik.age}") # 出力: 猫の名前: Barsik, 年齢: 5
属性初期化のためのメソッドの使用
この例では、属性の初期化にinitializeメソッドを使用している。Catオブジェクトは属性なしで作成され、その後initialize()メソッドを使って属性の値を設定する。
class Cat:
def initialize(self, name, age):
self.name = name
self.age = age
# Catオブジェクトの作成
barsik = Cat()
# メソッドを使った属性の初期化
barsik.initialize("Barsik", 5)
print(f"猫の名前: {barsik.name}, 年齢: {barsik.age}") # 出力: 猫の名前: Barsik, 年齢: 5
クラスフィールドの使用
この例では、属性nameとageはクラスレベルで定義されている。barsikオブジェクトの作成後、属性は直接初期化される。
class Cat:
name = ""
age = 0
# Catオブジェクトの作成
barsik = Cat()
# オブジェクト属性の初期化
barsik.name = "Barsik"
barsik.age = 5
print(f"猫の名前: {barsik.name}, 年齢: {barsik.age}") # 出力: 猫の名前: Barsik, 年齢: 5
どの方法がベストか?どれもベストではない!コンストラクタを使うのが一番だよ :)
4.2 コンストラクタ
コンストラクタは特別なメソッドで、 自動的に クラスの新しいオブジェクトが作成されたときに呼び出される。コンストラクタはオブジェクトのフィールドを初期化するために使用され、オブジェクトの設定に必要な初期アクションを実行できる。
Pythonでは、コンストラクタは__init__という名前のメソッドなんだ。これがその主なポイント:
- メソッド
__init__はPythonでのコンストラクタで、新しいクラスのインスタンスが作成されるときに自動的に呼び出される。 -
__init__は少なくとも一つのパラメータ、つまり作成されるオブジェクトを参照するselfを受け取る。それに加えて、オブジェクトの属性を初期化するために他のパラメータが与えられる可能性がある。 - メソッド
__init__の内部で、selfを使ってオブジェクトの属性に初期値を設定できる。 - コンストラクタは、入力データの検証や他のオブジェクトとの関係の設定など、オブジェクトの設定に必要なあらゆるアクションを実行できる。
パラメータはコンストラクタに自動的に渡される。オブジェクトを作成する際に丸括弧内にそれらを指定するだけでいい。
では、コンストラクタを使った猫の初期化がどうなるか見てみよう:
class Cat:
def __init__(self, name, age):
self.name = name
self.age = age
# 名前と年齢を持つCatオブジェクトの作成
barsik = Cat("Barsik", 5)
print(f"猫の名前: {barsik.name}, 年齢: {barsik.age}") # 出力: 猫の名前: Barsik, 年齢: 5
Cat型のオブジェクトが作成されると、メソッド__init__が自動的に呼び出され、3つのパラメータが渡されるよ:
- オブジェクトbarsikへの参照は
selfパラメータとして - 文字列「Barsik」は
nameパラメータとして - 数値5は
ageパラメータとして
使いやすくて美しいね。
データのバリデーション
また、コンストラクタ内でデータのバリデーションを行うこともできる。コンストラクタの目的は、有効な(正しい)オブジェクトを形成し、その後で作業を続けることができるようにすることだ。例を見てみよう:
class Cat:
def __init__(self, name, age):
if age < 0: raise ValueError("年齢はマイナスにできません")
self.name = name
self.age = age
# 年齢をチェックしてCatオブジェクトを作成
try:
barsik = Cat("Barsik", -3)
except ValueError as e:
print(e) # 出力: 年齢はマイナスにできません
GO TO FULL VERSION