Python3:类继承和私有字段

时间:2017-10-20 16:29:51

标签: python oop inheritance

我试图理解类继承在Python 3中是如何工作的,特别是私有字段如何与本地和继承方法交互。以下是一些例子来说明这个问题。

首先,如果超类中的变量var是公共的,那么子类中的任何方法也都可以改变它:

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

如果超类中的变量__var是私有的,则同样不是这样,任何继承的方法都将忽略子类所做的修改:

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!

子类中的本地方法可以改变它:

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

但是为了使用具有更改值的继承方法,我必须在子类中使用self._Superclass__var而不是self.__var

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

为什么会这样?私有字段是否未被子类继承,因此self.__var中的变量Subclass未指向self.__var内变量Superclass的相同值?

1 个答案:

答案 0 :(得分:3)

Python并不真正拥有私有变量,有两种约定:

  • 以下划线(_var)为前缀的变量用于让您和其他人知道它是私有的
  • 前缀为两个下划线(__var)的变量也会被python解释器破坏,并且还会以类名作为前缀,但在示例中仍然可以像self._Superclass__var那样访问它们

另请参阅documentation

您的代码中还有一个问题 - 您使用的是类变量,而不是实例变量(这通常称为其他语言中的静态类变量)。

检查此示例:

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

当您在方法中进行self.var = xxx分配时,您只需隐藏类级变量并添加具有相同名称的新实例级变量。

另请参阅文档:https://docs.python.org/3.6/tutorial/classes.html#class-and-instance-variables