问题描述
我试图了解 Python 3 中的类继承是如何工作的,特别是私有字段如何与本地和继承的方法交互.以下是一些示例来说明问题.
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.
首先,如果超类中的变量 var
是公共的,那么子类中的任何方法也可以改变它:
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
如果 Superclass 中的变量 __var
是私有的,则同样不是这样,任何继承的方法都会忽略子类所做的修改:
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
但是为了使用具有更改值的继承方法,我必须在子类中使用 self._Superclass__var
而不是 self.__var
:
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
为什么会这样?子类是否不继承私有字段,因此 Subclass
中的变量 self.__var
不指向变量 self.__var的相同值
超类
中的code>?
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
?
推荐答案
Python 并没有真正的私有变量,有两个约定:
Python doesn't really have private variables, there are two conventions:
- 以下划线前缀的变量 (
_var
) 用于让您和其他人知道它是私有的 - 以两个undersores (
__var
) 为前缀的变量也被python 解释器破坏,并且以类名为前缀,但它们仍然可以像self._Superclass__var
一样在你的例子
- 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
另请参阅文档.
您的代码中还有一个问题 - 您使用的是类变量,而不是实例变量(这在其他语言中通常称为静态类变量).
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).
检查这个例子:
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
赋值时,你只需隐藏类级变量并添加同名的新实例级变量.
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.
另见文档:https://docs.python.org/3.6/tutorial/classes.html#class-and-instance-variables
这篇关于Python3:类继承和私有字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!