One of Python's mottos is "we are all consenting adults". In other words, there's no language-level way to prevent someone from accessing data on an object or a method on an object. Naming conventions are the extent of the protection that you get; tack an underscore on to the front of a method and it's a hint that perhaps you shouldn't call it if you want to be polite.
This is a very practical attitude about the utility of language-level "private" methods, and it has served Python relatively well.
The problem is, this motto makes two assumptions:
The problem is that the first point is not true due to several unfortunate features of Python. For example, if I have a module "foo" that does
from lib import bar def buz(something): ... __all__ = ['buz']
and then a user of
qux to use foo like this:
from foo import bar
The name bar" is purely an implementation detail of "foo".
foo tried as hard as it could to say that: it set
__all__ to say
buz is the only thing you ought to be importing. Every single private implementation detail is exposed like this by default, unless you go out of your way to build special structures where these things are not exposed.
It would be nice to have a nicer default for imports so that wouldn't happen.