关于添加双下划线构成python私有成员(私有函数,私有变量)

我们都是成年人

we’re all consenting adults here —- What is “pythonic”?

python中并没有真正意义上的私有成员,它提供了在成员前面添加双下划线的方法来模拟类似功能。具体来说:

  • _xxx 表示模块级别的私有变量或函数
  • __xxx 表示类的私有变量或函数

这被称为name nangling,将__membername替换为_classname__membername。
这样从语法上实现了私有成员不能用classinstance.__membername访问,但是任然可以用
classinstance._classname__membername访问。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>> class Foo(object):
def __init__(self):
self.__baz = 42
def foo(self):
print self.__baz
>>> x = Foo()
>>> x.__dict__
{'_Foo__baz': 42}
>>> x.__baz
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
x.__baz
AttributeError: 'Foo' object has no attribute '__baz'
>>> x._Foo__baz
42

这样做更重要的目的是防止父类的同名成员被派生类重写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> class Foo(object):
... def __init__(self):
... self.__baz = 42
... def foo(self):
... print self.__baz
...
>>> class Bar(Foo):
... def __init__(self):
... super(Bar, self).__init__()
... self.__baz = 21
... def bar(self):
... print self.__baz
...
>>> x = Bar()
>>> x.foo()
42
>>> x.bar()
21
>>> print x.__dict__
{'_Bar__baz': 21, '_Foo__baz': 42}


参考:
https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references
https://docs.python.org/3.7/tutorial/classes.html#private-variables
http://stackoverflow.com/questions/70528/why-are-pythons-private-methods-not-actually-private