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.