1

consider the following code:

class animal:
    def __init__(self, name):
        self.__name = name

class dog(animal):
    def __init__(self, owner, name):
        self.__owner = owner
        super(dog, self).__init__(name)

terrier = dog('A', 'B')
terrier.owner = 'C'
terrier.name = 'D'
print(terrier._dog__owner, terrier._animal__name)
print(terrier.owner, terrier.name)

The output is:

A B
C D

I understand that Python private variables are only protected by convention. But all other threads mention ._className__attributeName eg. terrier._dog__owner as the only way of altering variable values. Here I am able to alter them even using terrier.owner or terrier.name.

Strangely, both give a different output as shown above. So do terrier.owner or terrier.name create different instances from terrier._dog__name or terrier._animal__name? What exactly has happened here?

7
  • 1
    Yes. There are no private attributes in Python. Commented Mar 25, 2016 at 18:33
  • 1
    Yes, terrier.owner is a different name from terrier._dog__owner. Why would you think otherwise? It's no different from doing terrier.blah = "foo". You can create whatever attributes you want. Commented Mar 25, 2016 at 18:34
  • Thanks but can you explain why the two separate instances of object terrier are being created that give two different sets of outputs? Commented Mar 25, 2016 at 18:35
  • @AnanyaChandra: you didn't create two separate instances.. Commented Mar 25, 2016 at 18:36
  • @AnanyaChandra: all you did was add additional attributes. Those are independent from the double-underscore attributes. Commented Mar 25, 2016 at 18:36

1 Answer 1

1

Double-underscore variables are indeed not private the way Java or C++ see privacy. They are not meant to be seen as private to code outside the class. They are used to avoid name clashes among subclasses, which is why the classname is used as a prefix.

E.g. when you have an internal implementation for a class Foo, and you don't want the subclass Bar(Foo) to accidentally use the same names in their implementation, you can use the attribute __spam, which will be transformed to _Foo__spam and _Bar__spam respectively, and thus won't clash.

The terrier.owner and terrier.name attributes you added are independent and have nothing to do with the _dog__owner and _animal__name attributes used by your classes. Using double-underscore variable names does not prevent other attributes from being created, including the same name without underscores.

Sign up to request clarification or add additional context in comments.

1 Comment

Coming from Java I thought terrier.__owner is a private version of terrier.owner. They are independent though with no relation whatsoever. Got it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.