Here is a quick, ugly way you can easily hide data, although persistent clients can still bypass it.  x.__dict__ is ugly, though not any uglier than x.__Ugly__Internal__Variable__Do__Not__Set<br><br>Another option would be to use another structure, such as a dictionary or list, and store variables in there proxying to it from get/set functions (or __getattr__ __setattr__).  Or just don't document this.<br>
<br>class HideTest(object):<br>    def __init__(self):<br>        self.__dict__["beans"] = 5<br>    def __setattr__(self,key,val):<br>        if key == "beans":<br>            raise Exception("Cannot set this attribute")<br>
        return super(HideTest,self).__setattr__(key,val)<br>        <br>b = HideTest()<br>print "b.beans is",b.beans<br>try:<br>    b.beans = 5<br>except:<br>    print "Cannot set"<br><br><br>Also the point of underscore rules have never been to keep clients from accessing variables.  Read about them in PEP8: <a href="http://www.python.org/dev/peps/pep-0008/">http://www.python.org/dev/peps/pep-0008/</a><br>
<br>They are primarily to handle specific name conflict situations, and secondarily to inform users when they might be mucking about with something at a lower level.  Using a keyword could work I suppose for the module-level convention, as well as for the name mangling.  Implementation wise it seems a bit tricky to use keywords for this.  For the purposes of informing users however, keywords versus underscore is a terrible idea.  dir() as is makes it clear, with underscores, which variables are safe to use and which are potentially dangerous.  Rewriting dir() to print extra information about names seems incredibly problematic as well.  I really like the idea of having variables that may be unsafe to use but I can still use them if I want to, and the underscore rules are the most clean way I can see for this purpose (not to mention all of the history).  I agree that they do look ugly of course.  I also tend not to use them in my code as well.  <br>
<br>This has been brought up so many times before, and turned down again and again.  Working around it as best you can is your best bet, especially since a major change like this could never happen until well after python 3.0.  (Who knows how long it will take before 3.0 is fully adopted enough to move on from that)<br>