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?
In Python, there is no existence of Private methods that cannot be accessed except inside a class. However, to define a private method prefix the member name with double underscore “__”. Note: The __init__ method is a constructor and runs as soon as an object of a class is instantiated.
The Python interpreter does not enforce this convention when working with classes, it's just a naming convention. Using private methods or private attributes allows you to show other developers which methods or attributes are “for internal use only” in a Python class.
A notable private method in Python is the __init__() method, which is used as a class constructor for a class object. This method is called when an object of a class is instantiated, depending on the method's arguments.
There are three types of access modifiers in Python: public, private, and protected. Variables with the public access modifiers can be accessed anywhere inside or outside the class, the private variables can only be accessed inside the class, while protected variables can be accessed within the same package.
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:
>>> 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With