0

私はPythonモジュールm1を持っています。

# m1.py
class C1(object):
    def __init__(self):
        self.__pri = 10
        self._pro = 5
        self.pub = 1

次に、bpythonで、

>>> import m1
>>> c = m1.C1()
>>> c.__pri
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'C1' object has no attribute '__pri'
>>> c._pro
5
>>> c.pub
1
>>> dir(c)
['_C1__pri', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_pro', 'pub']
>>> c._C1__pri
10

Pythonにはプライベート変数の概念はないと思いました。この動作を今どのように説明しますか?

編集:私はc .__ priに直接アクセスすることを期待していname manglingましたが、以下に答えるようにそれを行うことができないことがわかりました。皆さんありがとう!

4

3 に答える 3

5

二重アンダースコアは、単一のアンダースコアが前に付いた属性を持つクラス名をマングルします

    c._C1__pri

属性へのアクセスを許可します。一種の疑似プライバシーですが、他の用途もあります。で何が起こると思っていたのかわかりませんc.__privatec.__pri結果は同じだったでしょうが、 あなたはそうするつもりだったと思います。

この__pri属性はクラスの外部からアクセスできるためプライベートではありません。アクセスできるのはほんの数文字余分です。

以下で説明するjadkik94のように、これはアクセスを不可能にするためではなく、属性を使用してはならないことを別のプログラマーに通知するためです。

参考までに、これが役立つ可能性があるのは、継承を使用する場合です。

class Parent: 
    def __method(self): 
        print 'Parent method'

class Child(Parent): 
    def __method(self): 
        print 'Child method'

>>> c = Child()
>>> c._Child__method()
Child method
>>> c._Parent__method()
Parent method

二重アンダースコアは、名前が誤って上書きされるのを防ぎます(これは頻繁に見られるわけではありません)。

于 2012-12-26T15:21:43.030 に答える
1

名前マングリング

これは、プライベートクラスメンバーを宣言するメソッドを提供します。

この二重アンダースコアの名前マングリングは、サブクラスの内部プライベート変数の上書きを防ぐのに役立ちます。

メンバー変数を使用してはならないことを示す一般的な方法は、これは単なる慣例ですが、単一の下線で進めることです。

于 2012-12-26T15:22:09.027 に答える
1

観察しているのは名前マングリングです。この名前では、サブクラスとの偶発的な衝突を防ぎ、カジュアルなハッカーがプライベートフィールドを変更するのを防ぐために、先頭に2つのアンダースコアがあり、末尾に最大1つのアンダースコアがある変数の名前が変更されています。

ただし、マングリング後に変数の名前を判別するのは非常に簡単であるため、判別された病理学的ユーザーを失敗させることはありません。

于 2012-12-26T15:22:35.697 に答える