動画の解説を参照
前回の Studentクラスには、名前、学籍番号などのインスタンス変数を持たせました。
これらは外部から自由にアクセスできるため、ありえない値を入れることができてしまいます。
インスタンス変数の前にアンダーバーを2つつけると、外部からのアクセス (値の取得・変更) ができなくなります。
これを
隠蔽といいます。
実は、Pythonでの隠蔽はあまり強力なものではありません。
インスタンス変数にアンダーバーを2つつけると、内部的に変数の名前が変更されるだけです。具体的には
- __name → _Student__name
- __id → _Student__id
のようになります。上の実行結果で『「__name」という変数はありません』のようなエラーが出るのはそのためです。
つまり、「変更された名前」ならアクセスできてしまいます。
簡単に取得・変更ができないようにしたとはいえ、実際にはそうしたいケースもあります。
そのような場合は、メソッドを経由して行います。
変数の値を取得 (ゲット) するメソッドを作ると、間接的に値を取得して表示されられます。
このようなメソッドを
ゲッターといいます。
メソッド名は慣例的に「get_」のあとに変数名をつけたものにします。
逆に、引数を受け取って変数の値を変更するメソッドを作ると、それを経由して変数を書き換えられるようになります。
このようなメソッドを
セッターといいます。
メソッド名は慣例的に「set_」のあとに変数名をつけたものにします。
セッターとゲッターをあわせて、
アクセサーと呼びます。
アクセサーを経由してインスタンス変数にアクセスする形にすることを
カプセル化といいます。
上の Student クラスに学年を表す変数 __grade とそのゲッター・セッターを追加し、自分の情報を持ったインスタンス s を作り、
セッターを使って3つの情報を書き換え、ゲッターを使って情報を表示するコードを記述してください。
※ インスタンスの初期値は自分の情報にしてください。
※ 書き換える情報は、常識的に「ありえない値」にしてください。
(例)
動画の解説を参照
前項ではインスタンス変数を隠蔽したうえで、セッターを経由して書き換えました。
これだけではせっかく隠蔽した意味がありません。
そこで、セッターで引数の値を判定して、条件を満たさない場合は書き換えを行わないようにします。
例えば、set_name をこのようにすれば、少なくとも1文字以上の文字列を入れたときだけ変更が行われるようになります。
同様に、set_grade をこのようにすれば、1~4の整数を入れたときだけ変更が行われるようになります。
31から始まる7桁の整数を入れたときだけ変更が行われるように set_id を変更し、「整数でないもの」「許容範囲外の整数」「許容範囲内の整数」を入れて set_id を呼んだあとに introduce
で結果を確認するコードを書いてください。
※ インスタンスの初期値は自分の情報にしてください。
(例)
動画の解説を参照
カプセル化すると想定外の誤動作は避けられますが、アクセスのたびにゲッター・セッターを呼び出すのは面倒です。
そこで、クラス外からあたかもインスタンス変数を自由に取得・変更できているように見せる方法があります。
前項のようにゲッターとセッターを実装したクラスの最後にこのような記述を追加すると、
ゲッターの戻り値が普通に変数名で取得でき、「=」だけでセッターが呼び出されるようになります。
要するに、セッターでの例外処理を生かしたまま、隠蔽していないときのようにインスタンス変数にアクセスしているような記述ができるようになります。
Studentクラスに上記の修正を加え、名前、学籍番号、学年にそれぞれ「許容されないもの」「許容されるもの」を入れたあと、最後にそのインスタンスの情報を1行で表示するコードを記述してください。
(実行例)