A language like Java has strict protection against inappropriate access (but Python doesn't, as explained in other answers).
Java Example
Java's ArrayList is a good example of the use of private and protected members.
Looking at the linked source code, you will notice:
private int size;
-- size
is private because we don't want users fiddling with the size
of the ArrayList
directly. They are already able to add
, remove
, and clear
the List, so the ArrayList
class should maintain its own size
from these methods. Allowing the user to manipulate size
will only open the possibility of causing the size
to be incorrect (and thus causing an inconsistent data structure). Note that the user has the public int size()
method, so they are able to access the value of size
at any time, but not assign a new value to it.
protected void removeRange(int fromIndex, int toIndex)
-- This one is protected
because there are already other ways of removing a range of elements from an ArrayList (specifically using arrayList.subList(fromIndex, toIndex).clear();
, which eventually invokes ArrayList
's removeRange
method). Preventing unrelated classes from doing the same thing in multiple ways encourages cleaner and more consistent code - but to prevent redundancy, nested and child classes can still access these protected methods.
Python Example
While you can follow the same practices in Python, the language doesn't strictly prohibit access. Here is an example showing how you can still access protected and private members:
class MyClass(object):
def __init__(self, x, y):
self._x = x
self.__y = y
s = MyClass(1, 3)
print(dir(s))
print(s._x)
print(s._MyClass__y)
Output:
['_MyClass__y', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_x']
1
3
As you can see, __y
was detected as private and changed into _MyClass__y
, and _x
can still be accessed as _x
, even though it's marked as protected with the underscore.