Python: カプセル化と継承の基礎
最終更新:2026-09-22
カプセル化はオブジェクトの内部詳細を隠し、安全な操作インターフェースのみを公開します。継承により、あるクラスは自動的に別のクラスの機能を持ち、繰り返しを避けられます。これら 2 つの概念はオブジェクト指向プログラミングの根幹です。
1. カプセル化とプライベート属性
カプセル化とは、オブジェクトの内部データは外部から直接アクセスすべきでない——メソッドを通じて操作すべきであるという考え方です。
(1) シングルアンダースコア _ — 「保護された」属性の慣習
▶ サンプル:シングルおよびダブルアンダースコア
▶ 試してみよう出力:
# 函数定义成功
シングルアンダースコアは単なる慣習であり、強制はされません——Python はアクセスを妨げません。これは「これは内部用です、触らないでください」とドキュメントに書くようなものです。
(2) ダブルアンダースコア __ — 名前マングリング
▶ サンプル:銀行口座クラス
▶ 試してみよう出力:
# 函数定义成功
ダブルアンダースコアは名前マングリングをトリガーします——__balance は内部的に _BankAccount__balance に変換されます。これは真の「プライバシー」ではなく、偶発的なオーバーライドを防ぐためのものです。
private キーワードがありますが、Python にはなく、追加する予定もありません。
▶ サンプル:Temperature クラス(難易度 ⭐⭐)
▶ 試してみよう出力:
Temperature cannot be below absolute zero!
2. @property:エレガントなアクセス制御
set_celsius()/get_celsius() を書くのは冗長です。@property を使うと、属性アクセスの構文を保ちながらアクセスを制御できます:
▶ サンプル:@property の使用
▶ 試してみよう出力:
# 函数定义成功
@property の利点: 1)アクセスに括弧不要:t.celsius は t.get_celsius() より簡潔。2)代入時の自動検証:t.celsius = value は t.set_celsius(value) より簡潔。3)通常の属性を計算属性に変換しても、既存のコードを壊さない。
3. 継承
継承により、子クラスは親クラスのすべての属性とメソッドを持てます:
▶ サンプル:Animal の継承
▶ 試してみよう出力:
# 函数定义成功
(1) super():親メソッドの呼び出し
▶ サンプル:super() で親を呼び出す
▶ 試してみよう出力:
# 函数定义成功
4. Mixin パターン
Mixin は特殊なクラスです——独立して使われるのではなく、他のクラスに機能を追加するために「ミックスイン」されます:
▶ サンプル:Mixin パターン
▶ 試してみよう出力:
# 函数定义成功
Mixin で終わるものは、ミックスイン用であり、独立して使うためのものではないことを示します。クラスは複数の Mixin と 1 つのメインベースクラスをミックスインできます——深い単一継承よりもはるかに柔軟です。
5. よくあるユースケース
- データ検証:
@property.setterで代入時のデータ妥当性を確保 - 読み取り専用プロパティ:セッターなしの
@propertyで読み取り専用属性 - コード再利用:共通機能を基底クラスに配置。サブクラスは差分のみを記述
- 機能合成:Mixin を使って異なるクラスに柔軟に機能を追加
❓ よくある質問
@property と通常のメソッドの違いは何ですか?@property はメソッドを属性のように見せます——アクセスに括弧は不要、代入はセッターをトリガーします。本質的には「属性インターセプター」です——属性を操作しているかのようにコードを書きますが、実際にはメソッドが実行されます。class C(A, B)。ただし、多重継承には「ダイヤモンド問題」(両方の親に同じ名前のメソッドがある場合、どちらを使うか)があります。Python は MRO(メソッド解決順序)を使用し、左から右に検索します。Mixin は多重継承を活用するデザインパターンで、Mixin クラスは小さく機能的に独立しており、ダイヤモンド問題を回避します。📖 まとめ
- カプセル化:
_は「触るな」、__は名前マングリング、@propertyはエレガントなアクセス制御 - 継承:子クラスは自動的に親の属性とメソッドを持つ。
super()で親メソッドを呼び出す - メソッドオーバーライド:子クラスが親と同じ名前のメソッドを再定義
- Mixin:多重継承を使って柔軟に機能を追加。深い継承よりも推奨
- Python に真のプライベート属性はない——慣習と名前マングリングに依存
📝 練習問題
-
初級(難易度 ⭐):
Productクラスを定義し、price属性に@propertyを使用——設定時は正の値であることを要求、取得時は元の値を返す。 -
中級(難易度 ⭐⭐):3 レベルの継承
Animal→Mammal→Dog/Catを定義。Animalはnameとageを持ち、Mammalはfur_colorを追加、DogとCatはそれぞれ独自のspeak()メソッドを実装。 -
上級(難易度 ⭐⭐⭐):ログシステムを作成。
LoggableMixin(log_info()、log_error()メソッドを提供)と基底クラスApplication(name属性を持つ)を使用。WebAppとCLIAppの両方がApplicationを継承し、LoggableMixinをミックスインしてログ機能を実装。