Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonにおける二重アンダースコア(__)プレフィックスの役割とは?名前マングリングを解説

二重アンダースコアプレフィックス(ダブルアンダースコア)とは

Pythonでは、属性名の先頭に二重アンダースコア(__)を付けることで、その属性がクラスの外部から直接アクセス・参照できないようにすることができます。これは「名前マングリング(name mangling)」と呼ばれる仕組みで、Pythonインタプリタが属性名を自動的に書き換えることで実現されています。

ただし、特殊な構文を使えば外部からアクセスすること自体は可能です。しかし、それは一般的に推奨される方法ではありません。二重アンダースコアは、完全にプライベートな変数を定義したい場合に使用されます。

Python公式ドキュメントの記述

Pythonの公式ドキュメントには、以下のように記載されています。

クラスがサブクラス化されることを意図している場合、サブクラスに使用されたくない属性があるなら、先頭に二重アンダースコアを付け、末尾にはアンダースコアを付けない命名を検討してください。これにより、Pythonの名前マングリングアルゴリズムが呼び出され、クラス名が属性名に組み込まれます。これにより、サブクラスが誤って同じ名前の属性を持ってしまった場合でも、属性名の衝突を回避できます。

コード例

以下のコードは、二重アンダースコアの使用例を示しています。

class MyClass:
    __hiddenVar = 0
    def add(self, increment):
        self.__hiddenVar += increment
        print(self.__hiddenVar)

myObject = MyClass()
myObject.add(3)
myObject.add(8)
print(myObject.__hiddenVar)

実行結果

3
11
Traceback (most recent call last):
  File "C:/Users/TutorialsPoint1/.PyCharmCE2017.2/config/scratches/scratch_1.py", line 12, in <module>
    print(myObject.__hiddenVar)
AttributeError: MyClass instance has no attribute '__hiddenVar'

結果の解説

上記のプログラムでは、クラス内部のメソッドからは隠し変数 __hiddenVar に正常にアクセスでき、311 が出力されています。しかし、最後の行でオブジェクト経由でクラスの外部からこの変数にアクセスしようとしたところ、AttributeError 例外が発生しました。

これは、名前マングリングによって属性名が内部的に _MyClass__hiddenVar のように書き換えられているためです。つまり、外部からアクセスするには myObject._MyClass__hiddenVar と記述する必要がありますが、このようなトリッキーな方法の使用は避けるべきです。

なお、補足として、先頭に一重のアンダースコア(_var)を付けた場合は「慣習的なプライベート」を意味するに留まり、実際にアクセスが制限されるわけではない点も覚えておくと良いでしょう。二重アンダースコアによる名前マングリングは、継承時の属性名衝突を防ぐという実用的な目的を持った、より強力な仕組みです。

  1. Pythonの「print >>」構文とは?ファイルへの出力方法を解説

    「print >>」は、Python 2における標準のprintステートメントを拡張するための構文です。この構文を使うと、デフォルトの出力先であるsys.stdout(標準出力)ではなく、任意のファイルライクなオブジェクトに対して直接出力できるようになります。つまり、画面に表示する代わりに、ファイルやその他の出力ストリームへ直接書き込むことが可能になります。基本的な使い方例えば、「my_file」という名前のファイルを開いた場合、次のように書き込むことができます。>>> my_file = open(my_file, w) >>> print &

  2. Pythonの「%」演算子とは?文字列フォーマットの基本と使い方を解説

    Pythonの「%」演算子の役割 Pythonにおける「%(パーセント)」は、文字列フォーマット演算子(補間演算子)として機能します。「format % values」という形式で記述すると、フォーマット文字列内の変換指定子が、values側の要素によって置き換えられます。この仕組みは、C言語のsprintf()関数とよく似ています。 基本的な使い方:文字列の埋め込み 最もシンプルな例は、文字列の中に変数の値を埋め込むケースです。 >>> lang = Python >>> print %s is awesome! % lang Python is awe