17

次のような「プライベート」メソッドを持つクラスを考えてみましょう。

class Foo(object):
    def __init__(self):
        self.__method()
    def __method(self):
        print('42')

methodをサブクラス化Fooしてオーバーライドしようとすると、 の代わりに がまだ呼び出され__methodていることがわかります。Foo.__methodMoreFoo.__method

class MoreFoo(Foo):
    def __method(self):
        print('41')

>>> MoreFoo()
42
<__main__.MoreFoo object at 0x7fb726197d90>

そのようなメソッドをオーバーライドする方法は何でしょうか?

4

3 に答える 3

33

二重アンダースコアの命名規則を使用するポイントは、サブクラスが (誤って) メソッドをオーバーライドするのを防ぐことです

とにかくオーバーライドする必要がある場合は、誰かが重大なクラス設計エラーを犯しました。オブジェクトに名前を付けることで、まだそれを行うことができます:

def _Foo__method(self):

ここで、メソッド名の前にもう 1 つのアンダースコアと定義クラス名をプレフィックスとして付けます (したがって、この場合はプレフィックス を付け_Fooます)。2 つのアンダースコアを使用してメソッドと属性の名前を変更するプロセスは、プライベート ネーム マングリングと呼ばれます。

サブクラスでオーバーライド可能な「プライベート」メソッドを定義する場合は、通常、代わりにアンダースコアを 1 つ使用した名前に固執します ( def _method(self):)。

その動的な性質により、Python には真にプライベートなものはほとんどありません。少し内省するだけで、ほとんどすべてに到達できます。

于 2013-02-15T15:45:03.513 に答える
13

2 つのアンダースコア プレフィックスは、名前マングリングを呼び出します。これはプライベート メソッドと同等ではなく_Foo__method、サブクラスによってオーバーライドされないように特別に設計されています (この場合、メソッド名は になります)。

実装の詳細がある場合は、先頭にアンダースコアを 1 つ付けます。これは、外部で使用されない Python メソッドの一般的に受け入れられている記号です。これは、Python が機能する方法ではないため、これを強制するものではありません。

于 2013-02-15T15:44:45.667 に答える
7

私はあなたが次のようなことをすると信じています:

class MoreFoo(Foo):
    def _Foo__method(self):
        print('41')

文書化されているとおり。

フォームの任意の識別子__spam(少なくとも 2 つの先頭のアンダースコア、多くても 1 つの末尾のアンダースコア) はテキストで に置き換えられます_classname__spam。ここで、classnameは先頭のアンダースコアが削除された現在のクラス名です。

しかし、元のクラスの設計者は、サブクラス化によるオーバーライドを困難にすることが、最初の二重アンダースコアの要点であるため、このようなことを行う必要はないという意見でした。

名前マングリングは、クラス内メソッド呼び出しを中断することなく、サブクラスがメソッドをオーバーライドできるようにするのに役立ちます。

于 2013-02-15T15:45:01.623 に答える