Python 使我们能够通过在名称前添加双下划线来在类中创建“私有”方法和变量,如下所示:__myPrivateMethod(). 那么,如何解释这一点
__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()
我用公共方法和私有方法创建了一个类并实例化它。
接下来,我调用它的公共方法。
>>> 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() 揭示了 Python 为所有“私有”方法神奇地创建的新神奇方法。
>>> dir(obj) ['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
这个新方法的名字总是一个下划线,然后是类名,然后是方法名。
>>> obj._MyClass__myPrivateMethod() this is private!!
封装这么多,嗯?
无论如何,我总是听说 Python 不支持封装,那么为什么还要尝试呢?是什么赋予了?
名称加扰用于确保子类不会意外覆盖其超类的私有方法和属性。它的设计目的不是为了防止从外部故意访问。
例如:
>>> 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}
当然,如果两个不同的类具有相同的名称,它就会崩溃。