6

今日、私はそれを見る-pythonは_$CLASSNAME$、名前が。のメソッドに追加します__

簡単な例:

>>> class A:  
...     def a(self):  
...         self.b()  
...     def b(self):  
...         print('A.b')  
...           
>>> class B(A):  
...     def b(self):  
...         print('B.b')  
...           
>>> B().a()  
B.b

それは機能しますが、:

>>> class A:  
...     def a(self):  
...         self.__b()  
...     def __b(self):  
...         print('A.b')  
...           
>>> class B(A):  
...     def __b(self):  
...         print('B.b')  
...           
>>> B().a()  
A.b

なんで?わからないので、汚しました。ここにあります:

>>> print([fn for fn in dir(B) if fn[-2:] != '__'])
['_A__b', '_B__b', 'a']

なぜPythonはそれをするのですか?それを回避する方法はありますか?

4

2 に答える 2

12

これは名前マングリングと呼ばれ、親クラスと子クラスとの偶発的な名前の衝突を防ぐために行われます。これを無効にすることはできません (多くの完全に優れたコードで使用されているため、無効にする必要はありません)。これを回避することはできますが、それを行うべきではありません (非常に醜いので回避できます。また、アクセスする必要がある場合は、最初から名前マングリングを許可しないでください)。クラス内のどこでも使用したいプライベート関数には、単一のアンダースコアを使用するだけです。

チュートリアルを参照してください。ただし、「プライベート」変数を示す this への参照は無視してください。privateC++/Java/C#/...変数の意味で使用しない限り、それは使用されませんprivate(子クラスに表示されるものとは対照的にprotected)子クラスから隠されています。それでも、それは欠陥のあるアナロジーです。

于 2012-08-24T21:50:28.103 に答える
11

これはいずれもPythonによって厳密に強制されるものではありませんが、二重アンダースコアの命名規則は「プライベート」を意味し、単一アンダースコアは「保護」を意味します。

二重アンダースコアは、同じ名前を使用してサブクラスがエラーを引き起こすのを防ぐためのものです。それらをクラス名で名前空間化することにより、定義クラスはその変数が引き続き有効であることを確認できます。

単一の下線は、サブクラスがそれらの同じ属性に自由にアクセスして変更できることを意味し、スーパークラスと共有されます。

どちらの形式も、外部クラスがこれらにアクセスしてはならないことを示しています

class A(object):

    __private = 'private'
    _protected = 'protected'

    def show(self):
        print self.__private 
        print self._protected

class B(A):
    __private = 'private 2'
    _protected = 'protected 2'

a = A()
a.show()
#private
#protected

b = B()
b.show()
#private
#protected 2

この例は、クラスBがnewを定義したとしても、元のスーパークラス属性にアクセスする__private継承されたメソッドには影響しないことを示しています。ただし、これらは同じ属性であるため、変更され、スーパークラスメソッドはこれを反映します。show_protectedshow

于 2012-08-24T21:57:56.303 に答える