If your class is intended to be subclassed, and you have attributes that you do not want subclasses to use, consider naming them with double leading underscores and no trailing underscores. This invokes Python's name mangling algorithm, where the name of the class is mangled into the attribute name. This helps avoid attribute name collisions should subclasses inadvertently contain attributes with the same name.

Private variables and methods are just name mangling in Python. We can access a private variable by using _ClassName__private_var_name.

class Foo:
    def __init__(self):
        self.__private_var = 12
    def __private_method(self):
        return 'Private method invoked'
    def greetings(self):
        return 'Hello World!'
>>> foo = Foo()
>>> foo.greetings()    # public method
'Hello World'  # output
>>> foo._Foo__private_var    # private variable
12  # output
>>> foo._Foo__private_method()    # private method
'Private method invoked'  # output