You can use a leading underscore in the name to tell readers of the code that the name in question is an internal detail and they must not rely on it remaining in future versions. Such a convention is really all you need -- why weigh the language down with an enforcement mechanism?
Data, just like methods, should be public (named without a leading underscore) if they're part of your class's designed API which you intend to support going forward. In C++, or Java, that's unlikely to happen because if you want to change the data member into an accessor method, you're out of luck -- you'll have to break your API and every single client of the class will have to change.
In Python, and other languages supporting a property
-like construct, that's not the case -- you can always replace a data member with a property which calls accessor methods transparently, the API does not change, nor does client code. So, in Python and other languages with property
-like constructs (I believe .NET languages are like that, at source-code level though not necessarily at bytecode level), you may as well leave your data public when it's part of the API and no accessors are currently needed (you can always add accessor methods to later implementation releases if need be, and not break the API).
So it's not really a general OO issue, it's language specific: does a given language support a property-like construct. Python does.