Members in Python are never private. Variables that are supposed to be used internally only are marked with and underscore, but that just conveys intent and isn't enforced by the interpreter/runtime. But you can emulate private data like this:
>>> def a(u, v):
... def b():
... return u + v
... return b
...
>>> b = a(1,2)
>>> b()
3
Like this, there is no way to access u & v from b.
When using it like this, the interpreter opens a new namespace where the variables are bound. The x is declared in the outer scope, so it can't find it. However, you can ask python to keep searching vor the name `x` in the closest outer scope, that is what the `nonlocal` statement is for:
def f():
x = 5
class Blub:
def incx(self):
nonlocal x
x += 1
def getx(self):
return x
return Blub()
j = f()
j.incx()
print(j.getx())
That’s not their purpose and they’re not really private. Leading double underscore methods cause name mangling (the class name gets added to the method name) and they’re used for solving specific problems with inheritance. Don’t use them just to make something private. You’re screwing up your inheritance if you don’t realize what you’re doing.
Leading single underscore is private by convention. Still should generally be avoided, but it’s the proper use.
They're only private in a sense that you're not supposed to access them, there's no enforcement by the language in any way beyond renaming them `_<class>__<attr>`. They're still accessible and they still show up in `dir`, `__dict__`, etc.