Python 使我们能够通过在名称前添加双下划线来在类中创建“私有(private)”方法和变量,例如:__myPrivateMethod()
。那么,如何解释这一点
>>>> class MyClass:
... def myPublicMethod(self):
... print 'public method'
... def __myPrivateMethod(self):
... print 'this is private!!'
...
>>> obj = MyClass()
>>> obj.myPublicMethod()
public method
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
>>> obj._MyClass__myPrivateMethod()
this is private!!
怎么了?!
我会为那些不太明白的人解释一下。
>>> class MyClass:
... def myPublicMethod(self):
... print 'public method'
... def __myPrivateMethod(self):
... print 'this is private!!'
...
>>> obj = MyClass()
我用公共(public)方法和私有(private)方法创建了一个类并实例化它。
接下来,我调用它的公共(public)方法。
>>> obj.myPublicMethod()
public method
接下来,我尝试调用它的私有(private)方法。
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
这里的一切看起来都不错;我们无法调用它。事实上,它是“私有(private)的”。嗯,实际上并非如此。在对象上运行 dir()
揭示了一种新的神奇方法,Python 神奇地为你的所有“私有(private)”方法创建了这种方法。
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
这个新方法的名称始终是一个下划线,后跟类名,然后是方法名。
>>> obj._MyClass__myPrivateMethod()
this is private!!
封装这么多,嗯?
无论如何,我一直听说 Python 不支持封装,那么为什么还要尝试呢?什么给了?
最佳答案
名称加扰用于确保子类不会意外覆盖其父类(super class)的私有(private)方法和属性。它并非旨在防止从外部故意访问。
例如:
>>> 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}
当然,如果两个不同的类具有相同的名称,它就会崩溃。
关于python - 为什么 Python 的 'private' 方法实际上不是私有(private)的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70528/