Python gives us the ability to create 'private' methods and variables within a class by prepending double underscores to the name, like this: __myPrivateMethod(). How, then, can one explain this
>>>> 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!! What's the deal?!
I'll explain this a little for those who didn't quite get that.
>>> class MyClass: ... def myPublicMethod(self): ... print 'public method' ... def __myPrivateMethod(self): ... print 'this is private!!' ... >>> obj = MyClass() I create a class with a public method and a private method and instantiate it.
Next, I call its public method.
>>> obj.myPublicMethod() public method Next, I try and call its private method.
>>> obj.__myPrivateMethod() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: MyClass instance has no attribute '__myPrivateMethod' Everything looks good here; we're unable to call it. It is, in fact, 'private'. Well, actually it isn't. Running dir() on the object reveals a new magical method that Python creates magically for all of your 'private' methods.
>>> dir(obj) ['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod'] This new method's name is always an underscore, followed by the class name, followed by the method name.
>>> obj._MyClass__myPrivateMethod() this is private!! So much for encapsulation, eh?
In any case, I'd always heard Python doesn't support encapsulation, so why even try? What gives?