patternpythonCritical
Why are Python's 'private' methods not actually private?
Viewed 0 times
whyprivatemethodspythonnotactuallyare
Problem
Python gives us the ability to create 'private' methods and variables within a class by prepending double underscores to the name, like this:
What's the deal?!
I'll explain this a little for those who didn't quite get that.
I create a class with a public method and a private method and instantiate it.
Next, I call its public method.
Next, I try and call its private method.
Everything looks good here; we're unable to call it. It is, in fact, 'private'. Well, actually it isn't. Running
This new method's name is always an underscore, followed by the class name, followed by the method name.
So much for encapsulation, eh?
In any case, I'd always heard Python doesn't support encapsulation, so why eve
__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()I create a class with a public method and a private method and instantiate it.
Next, I call its public method.
>>> obj.myPublicMethod()
public methodNext, 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 eve
Solution
The name scrambling is used to ensure that subclasses don't accidentally override the private methods and attributes of their superclasses. It's not designed to prevent deliberate access from outside.
For example:
Of course, it breaks down if two different classes have the same name.
For example:
>>> 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}Of course, it breaks down if two different classes have the same name.
Code Snippets
>>> 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}Context
Stack Overflow Q#70528, score: 716
Revisions (0)
No revisions yet.