1

I have the following classes:

class A:
    def name(self):
        return self.__label

class B(A):
    def __init__(self, name)
        self.__label = name

ex1 = B('Tom')
print ex1.name()

What I get is:

AttributeError: B instance has no attribute '_A__label'

What's wrong and how to correct it?

Physicist
  • 2,848
  • 8
  • 33
  • 62
  • 4
    What's wrong: you're using double-underscore variables. How to fix it: don't use double-underscore variables. – Daniel Roseman Nov 12 '15 at 22:10
  • why isn't it allowed? It is hidden from the outside world, but I am using a method defined inside a parent class. Why is there a problem? – Physicist Nov 12 '15 at 22:14
  • 1
    Because double-underscores are there *precisely* to stop access (or overwriting) by parent or child classes. They are almost never what you want; don't use them. – Daniel Roseman Nov 12 '15 at 22:14
  • then how can I stop access from the outside world (e.g. unintentional access by users) but allow access from parent / child classes? – Physicist Nov 12 '15 at 22:16
  • [use a single underscore](https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references) – Gerrat Nov 12 '15 at 22:16
  • 2
    Don't. Just: don't. The Python principle is "we're all consenting adults here". By all means, give your attributes a single underscore, to make it clear that they shouldn't be accessed unless you know what you're doing, but you can't stop people from doing it anyway and you shouldn't try. – Daniel Roseman Nov 12 '15 at 22:18

1 Answers1

1

When you prefix an attribute with a double underscore, Python uses 'name mangling' to access the attribute. This means it will store the attribute on the class in the format: _<class name>__<attr name>. In your example self.__label will be stored as self._B__label because you set it in the B class method. But when you try to use the attribute in the A class it converts self.__label into self._A__label and finds that it isn't set.

The use case for double underscores is when you want to ensure that your variable is always on your class even if a subclass derives your class. Because what could happen is that the subclass redefines your variable to something else, using double underscored variables makes this that much harder.

Barry Rogerson
  • 598
  • 2
  • 15