5

The following code generates an error:

class A(object):
    def say_something(self):
        print(self.foo)
        print(self.__bar)

class B(A):
    def __init__(self):
        self.foo = 'hello'
        self.__bar = 'world'

test = B()
test.say_something()

Printing of 'hello' is successful but 'world' generates the following error:

    print(self.__bar)

AttributeError: 'B' object has no attribute '_A__bar'

I am surprised by this, I would like my parent class to have a method which has access to a private attribute its children are guaranteed to have. Is there some standard way of solving this problem?

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
Mike Vella
  • 10,187
  • 14
  • 59
  • 86
  • You may find the following question helpful: [The meaning of a single- and a double-underscore before an object name in Python](http://stackoverflow.com/questions/1301346/the-meaning-of-a-single-and-a-double-underscore-before-an-object-name-in-python) – Greg Hewgill May 29 '12 at 22:38

3 Answers3

12

You can use self._B__something to access it. However, this is not what yuo should do. The proper solution is renaming __bar to _bar.

The idea behind the double-underscore name mangling is to avoid conflicts with subclasses/superclasses - it's not meant to be used for private variables. If a variable should be considered private/internal, prefix it with a single underscore. This does not cause any special treatment but every python developer will know that it's not part of the public API of the class/module containing that variable.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • Exactly. The intention of the name mangling mechanism is to get exactly the behavior the OP is seeing here. It is meant to make a member element be linked to 1 and only 1 scope. – Silas Ray May 29 '12 at 22:46
  • Got it. I found the same thing you are saying here http://docs.python.org/tutorial/classes.html I suppose I'm still a bit uncomfortable with the idea of nothing being truly private. – Mike Vella May 29 '12 at 23:07
  • Well, even in a language with "real" private variables there are always ways (reflection or messing around with the memory) to access them. Python simply assumes programmers are smart so it doesn't truly enforce private variables. – ThiefMaster May 29 '12 at 23:34
1

It's name mangling. Any member that starts with double underscores gets name mangled in Python. Your code would work with any other members, as long as they didn't start with double underscore.

Silas Ray
  • 25,682
  • 5
  • 48
  • 63
-1

I suspect you are missing something in your code.. I don't see __bar in either class A or class B..

cgcoder
  • 426
  • 4
  • 11