Python のクラスには public/private の概念がないため、アンダースコアで始まるものは自分で作成しない限り触らないように言われます。しかし、これには、直接的または間接的に継承するすべてのクラスの完全な知識が必要ではないでしょうか? 目撃者:
class Base(object):
def __init__(self):
super(Base, self).__init__()
self._foo = 0
def foo(self):
return self._foo + 1
class Sub(Base):
def __init__(self):
super(Sub, self).__init__()
self._foo = None
Sub().foo()
期待どおり、が評価されると aTypeError
が発生します。したがって、それが基本クラスに存在するNone + 1
ことを知っておく必要があります。_foo
これを回避するには、__foo
代わりに を使用できます。これは、名前を変更することで問題を解決します。これは、エレガントではないにしても、許容できる解決策のようです。しかし、Base
(別のパッケージにある) というクラスから継承するとどうなるSub
でしょうか? 今、祖父母の__foo
私のSub
オーバーライドにあります。__foo
Sub
これは、それぞれが使用するすべての「プライベート」オブジェクトを含む、継承チェーン全体を知る必要があることを意味します。Python が動的に型付けされるという事実は、検索する宣言がないため、これをさらに困難にします。ただし、最悪の部分は、おそらく現在はBase
から継承される可能性がありobject
ますが、将来のリリースでは からの継承に切り替わることSub
です。が継承されていることがわかっている場合Sub
は、クラスの名前を変更できますが、それは面倒です。でも未来が見えない。
これは、真のプライベート データ型が問題を防ぐケースではありませんか? Python では、将来ある時点で誰かのつま先が出現する可能性がある場合、誤って誰かのつま先を踏んでいないことをどのように確認できますか?
編集:私は明らかに主な質問を明確にしていません。私は名前マングリングと、単一アンダースコアと二重アンダースコアの違いに精通しています。問題は、現在その存在を知らないクラスと衝突する可能性があるという事実にどのように対処するかです。私の親クラス (私が書いたのではないパッケージに含まれています) がたまたま私のクラスと同じ名前のクラスから継承を開始した場合、名前マングリングでさえ役に立ちません。これを、真のプライベートメンバーが解決する(コーナー)ケースと見なすのは間違っていますが、Pythonには問題がありますか?
編集: 要求されたとおり、以下は完全な例です。
ファイルparent.py
:
class Sub(object):
def __init__(self):
self.__foo = 12
def foo(self):
return self.__foo + 1
class Base(Sub):
pass
ファイルsub.py
:
import parent
class Sub(parent.Base):
def __init__(self):
super(Sub, self).__init__()
self.__foo = None
Sub().foo()
祖父母のfoo
ものは呼ばれますが、私の__foo
ものは使われます。
明らかに、このようなコードを自分で作成することはありませんがparent
、第三者から簡単に提供される可能性があり、その詳細はいつでも変更される可能性があります。