Pythonのクラスにてイミュータブルなインスタンス変数を定義できるかを検証しました。
より成長させやすいコードの書き方と設計を学ぶ入門書である、
良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方
の内容をPythonにて実装/検証に挑戦します。
【3.2 章 成熟したクラスに成長させる設計術】
良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方
<3.2.3. 不変で思わぬ動作を防ぐ>
変数の値が変わる前提だと、いつ変更されたのか、今の値がどうなっているのかをいちいち気にしなければなりません。
仕様変更で処理が変わったとき、意図しない値に書き変わる、いわゆる「思わぬ副作用」が容易に発生します。
これを防止するために、インスタンス変数をを不変(イミュータブル)にします。
「良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方」
- より成長させやすいコードの書き方と設計を学ぶことができる入門書
- 「悪いコード/アンチパターン」をベースに説明、より実践的な例で理解を深めることができる
- オブジェクト指向言語であるPython/C++に役立つ内容が満載
【結論】イミュータブルな変数をコンストラクタにて定義するのは難しい
今回は以下の2つの方法にて、イミュータブルな変数をコンストラクタにて定義することができるかを検証しました。
- 型ヒントライブラリであるtypingよりFinal型チェッカーの活用
- 暗黙知によるprotected変数、private変数の活用
型ヒントライブラリであるtypingよりFinal型チェッカーの活用
pythonではtypingによる型ヒントのサポートが提供されております。
その中でも、イミュータブルな変数であることを示すFinalによる型チェッカーを活用します。
特別な型付けの構成要素で、名前の割り当て直しやサブクラスでのオーバーライドができないことを型チェッカーに示すためのものです。
typingによる型ヒントのサポート
ただし、あくまで「型チェッカー」であるため、変更操作そのものは可能となります。
class ClassSample():
def __init__(self):
self.str2: Final[str] = "not changed" # イミュータブルである型ヒントを追加
暗黙知によるprotected変数、private変数の活用
Pythonではクラスのメンバ変数の接頭辞にアンダーバーをつけることにより、以下のような定義になります。
- アンダーバーが1つ:暗黙知によるprotected変数
- アンダーバーが2つ:private変数
class ClassSample():
def __init__(self):
self._str3 = "not changed" # 暗黙知なprotected変数
self.__str4 = "not changed" # private変数
アンダーバーが2つによるprivate変数では、クラス外からの変更は不可となりますが、
クラス内では変更可能(ミュータブル)となり、イミュータブルな変数として取り扱うことはできません。
【実装】イミュータブルなインスタンス変数を定義できるかの検証
【まとめ】イミュータブルな変数を定義できる?(良いコード/悪いコード実践)
良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方より、
「不変で思わぬ動作を防ぐ」をPythonにて実現できるかを検証しました。
現状、Pythonのクラスにて、イミュータブルな変数をコンストラクタにて定義するのは難しいです。
今回は実現することができませんでしたが、
良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方では
Pythonユーザーにとって、より成長させやすいコードの書き方と設計を学ぶことができる入門書です!
「良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方」
- より成長させやすいコードの書き方と設計を学ぶことができる入門書
- 「悪いコード/アンチパターン」をベースに説明、より実践的な例で理解を深めることができる
- オブジェクト指向言語であるPython/C++に役立つ内容が満載