问题
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
?
回答1:
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 likeself._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
来源:https://stackoverflow.com/questions/46853442/python3-class-inheritance-and-private-fields