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 "", line 1, in 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()

What I did there is 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 "", line 1, in 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?