4

I am trying to understand how class inheritance works in Python 3, in particular how private fields interact with local and inherited methods. Here are some examples to illustrate the issue.

First, if a variable var in the Superclass is public, then any method in the Subclass will also be able to alter it:

class Superclass:
    var = 1
    def getVar(self):
        print(self.var)

class Subclass(Superclass):
    def __init__(self):
        self.var = 123

my_object = Subclass()
my_object.getVar() # outputs 123

The same is not true if the variable __var in the Superclass is private, any inherited method will ignore modifications done by the Subclass:

class Superclass:
    __var = 1
    def getVar(self):
        print(self.__var)

class Subclass(Superclass):
    def __init__(self):
        self.__var = 123

my_object = Subclass()
my_object.getVar() # outputs 1!

Local methods in the Subclass can alter it:

class Superclass:
    __var = 1

class Subclass(Superclass):
    def __init__(self):
        self.__var = 123
    def getVar(self):
        print(self.__var)

my_object = Subclass()
my_object.getVar() # outputs 123

But in order to use an inherited method with the altered value, I must use self._Superclass__var instead of self.__var in the Subclass:

class Superclass:
    __var = 1
    def getVar(self):
        print(self.__var)

class Subclass(Superclass):
    def __init__(self):
        self._Superclass__var = 123

my_object = Subclass()
my_object.getVar() # outputs 123

Why is this the case? Are private fields not being inherited by the subclasses and therefore the variable self.__var inside the Subclass is NOT pointing to the same value the variable self.__var inside Superclass?

4
  • 6
    There are no private fields in Python. If you prefix an attribute name with __ you invoke name mangling, where the name of the "owning" class is automatically inserted so as to help prevent attribute names from conflicting in subclasses. It doesn't prevent you from accessing it, it just requires that you include the owning class's name. See docs.python.org/3/tutorial/classes.html#private-variables Commented Oct 20, 2017 at 16:33
  • 4
    There are no private fields in Python. That is your fundamental misunderstanding. You are using double-underscore name-mangling, which it to prevent name-collisions in inherited classes, not to prevent access. As an aside, I hope you realize you are defining class level variables, equivalent to "static variables" in other languages, rather than instance variables. Commented Oct 20, 2017 at 16:36
  • 1
    I think it worth addition this clarification as an answer as it is a good question for people coming with different background. Commented Oct 20, 2017 at 16:44
  • thank you all for the comments and clarifications. If @kindall would post his comment as an answer, I would gladly accept it. Commented Oct 20, 2017 at 17:09

1 Answer 1

4

Python doesn't really have private variables, there are two conventions:

  • Variables prefixed with underscore (_var) are used to let you and other people know that it's intended to be private
  • Variables prefixed with two undersores (__var) are also mangled by python interpreter and also are prefixed by class name, but they are still accessible like self._Superclass__var in your example

See also the documentation.

There is one more issue in your code - you are using class variables, not instance variables (this is what usually called static class variables in other languages).

Check this example:

class Superclass:
    var = 1

    def getVar(self):
        print(self.var)

my_object = Superclass()
my_object2 = Superclass()
my_object.getVar()  # outputs 1
my_object2.getVar()  # outputs 1

Superclass.var = 321  # this value is share across all instances
my_object.getVar()  # outputs 321
my_object2.getVar()  # outputs 321

And when you are doing self.var = xxx assignments in your methods, you just hide the class-level variable and add the new instance-level variable with same name.

See also the documentation: https://docs.python.org/3.6/tutorial/classes.html#class-and-instance-variables

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

1 Comment

Since the author of those comments did not write an answer that I could select, would you care to add that information to your answer above so I can select it? Because right now, as helpful as your answer is, it is not exactly addressing the issue I raised.

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.