Generally speaking in canonical OOP situations, the rule of thumb is to write your classes with the least access as necessary. i.e. only make public only what is necessary, make protected only what is necessary, etc etc. (There are exceptions and what I describe does not always apply. FWIW, I find the idea of "least access as necessary" to be useful in more canonical OO C++/Java situations.)
However in Python, you don't have strict access modifiers like public, protected, private, etc. Python has pseudo protected and pseudo private in the form of single _ and double __ underscores for your object fields and methods.
In more "canonical OO"[1] Python situations, what is the rule of thumb for default access modifiers?
Is the rule of thumb to restrict more (like in C++/Java) and qualify all fields/methods with __ until there is a requirement/design/API need to make it public or protected?
Or is the rule of thumb to start with all your python fields/methods as public and restrict them as needed?
I have seen some who default to protected with _ and use pylint to catch breaking encapsulation. I can also see others who would default to private. And I'm sure there are still others who default to public.
[1] I use the term "canonical OO" to refers to more of what I would call textbook OO programming theory/situations. In my experience real programming often differs from textbook OO or canonical OO programming theory.
protectedandprivatein Python's context because I don't think it relates very well to the same concept in, say, Java.foo.foo,foo._barandfoo.__Foo_baz).