Keep your place in this quest

Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.

オブジェクト指向プログラミングでは、すべてのデータやメソッドがクラスの外部から直接アクセスされるわけではありません。時には、内部の詳細を隠し、クラス内部でのみ使用できるようにしたいことがあります。

Pythonでは、属性やメソッドがプライベートであることを示すには、名前の先頭にダブルアンダースコア__)を付けます。

これはアクセスを完全に不可能にするわけではありませんが、名前修飾(name mangling)という機能が有効になり、属性の名前が内部的に変更され外部からアクセスしにくくなります。


プライベートメンバーを使う理由

プライベート属性やメソッドは:

  • データが誤って変更されるのを保護します。
  • クラス内部のどの部分が内部用で、外部コードから頼るべきでないかを明確にします。
  • クラスを使う他のコードを壊さずに内部実装を変更できるようにします。

重要:Pythonにおけるプライバシーは強制ではなく慣習です。プライベートメンバーは本気でアクセスしようとすればアクセス可能ですが、そうしないことを意図しています。


例:Personクラス

class Person:
    def __init__(self, name, age):
        self.name = name          # パブリック属性
        self.__age = age          # プライベート属性

    def print_name(self):
        print("Name:", self.name)

    def print_info(self):
        self.print_name()
        self.__print_age()        # クラス内部からプライベートメソッドを呼び出す

    def __print_age(self):        # プライベートメソッド
        print("Age:", self.__age)

p = Person("John", 30)

p.print_name()        # 動作する: Name: John
p.print_info()        # 動作する: Name: John  Age: 30

プライベート属性へ外部からアクセスするとどうなる?

クラスの外から直接プライベートメンバーにアクセスしようとすると、AttributeErrorが発生します:

p = Person("John", 30)
print(p.__age)  # ❌ エラーになる

なぜ? Pythonは名前__ageを内部的に_Person__ageに自動変換(名前修飾)しているからです。これは偶発的なアクセスやサブクラスとの名前衝突を防ぎます。


プライベートデータへアクセスしたい場合(どうしても必要なら)

技術的には、修飾された名前を使ってプライベートメンバーにアクセスできます:

print(p._Person__age)  # 30

しかしこれはプライバシーの概念を壊す行為であり、通常のプログラムロジックではなくデバッグなどの特別な場合にのみ使うべきです。


プライベートメソッド

属性と同様に、メソッドもダブルアンダースコアでプライベートにできます。 例では__print_age()がプライベートで、クラス外から呼び出すことはできません:

p.__print_age()  # ❌ エラーになる

しかしprint_info()内のようにクラス内部からは問題なく呼び出せます。

プライベートメンバーを使うタイミング

プライベートの属性やメソッドは、以下の場合に使います:

  • クラスの内部部分の誤用を防ぎたいとき。
  • データのアクセスや変更を制御したいとき(多くの場合はgetterやsetterと組み合わせる)。
  • クラスのパブリックAPI(外から使うもの)と実装の詳細を明確に分けたいとき。

まとめ

Pythonにおけるプライベートメンバーは:

  • 名前が__(ダブルアンダースコア)で始まる。
  • 内部利用限定を意図している。
  • 名前修飾で技術的にはアクセス可能だが、プライバシーを尊重すべき。

これは他のプログラマー(そして将来自分自身)に対して、何が安全に使えて何が内部詳細で後から変更される可能性があるかを示すサインなのです。