Python 父类有一个支持实例
假设我有以下代码:Python 父类有一个支持实例,python,inheritance,Python,Inheritance,假设我有以下代码: class ParentClass(): myList=[] 定义初始化(自): 打印(“父类构造函数”) 儿童班(家长班): 定义初始化(自): 打印(“子构造函数”) def添加元素(自身,项目): self.myList.append(项) 打印(f“按子项A添加项,当前长度:{len(self.myList)}”) 儿童B类(家长类): 定义初始化(自): 打印(“子B构造函数”) def添加元素(自身,项目): self.myList.append(项) 打印(f“
class ParentClass():
myList=[]
定义初始化(自):
打印(“父类构造函数”)
儿童班(家长班):
定义初始化(自):
打印(“子构造函数”)
def添加元素(自身,项目):
self.myList.append(项)
打印(f“按子项A添加项,当前长度:{len(self.myList)}”)
儿童B类(家长类):
定义初始化(自):
打印(“子B构造函数”)
def添加元素(自身,项目):
self.myList.append(项)
打印(f“按子项B添加项,当前长度:{len(self.myList)}”)
a=ChildA()
a、 增加要素(1)
a、 增加要素(1)
b=ChildB()
b、 增加要素(1)
当我运行它(Python 3.9.3)时,我得到以下输出:
Child A constructor
Added item by Child A, current length: 1
Added item by Child A, current length: 2
Child B constructor
Added item by Child B, current length: 3
这表明子类从中继承的父类有一个备份实例,因为我没有在构造函数中将myList
显式设置为[]
,所以它使用相同的备份内存,即使对于两个不同的子类也是如此
myList
显式设置为[]
来解决这个问题,但我对这个行为感到困惑,因为它不是我所期望的行为(我希望在第一次调用ChildB
之后myList
的长度为1)
我只是通过在父构造函数中将myList显式设置为[]来解决这个问题,但我对这个行为感到困惑,因为它不是我所期望的行为
没错。您所做的是在类本身上定义变量,而不是在类的实例上定义变量。定义实例变量的正确方法是在构造函数中
class ParentClass():
def __init__(self):
print("Parent class constructor")
self.myList = []
如果要避免这种情况,可以在每个子类的
\uuuuu init\uuuu
方法中声明列表:
class ParentClass():
def __init__(self):
self.myList = []
print("Parent class constructor")
class ChildA(ParentClass):
def __init__(self):
self.myList=[]
print("Child A constructor")
def add_elem(self, item):
self.myList.append(item)
print(f"Added item by Child A, current length: {len(self.myList)}")
class ChildB(ParentClass):
def __init__(self):
self.myList=[]
print("Child B constructor")
def add_elem(self, item):
self.myList.append(item)
print(f"Added item by Child B, current length: {len(self.myList)}")
a = ChildA()
a.add_elem(1)
a.add_elem(1)
b = ChildB()
b.add_elem(1)
输出:
Child A constructor
Added item by Child A, current length: 1
Added item by Child A, current length: 2
Child B constructor
Added item by Child B, current length: 1
是的,只有一个
myList
你忘了调用父构造函数,这不会有帮助:父构造函数永远不会被调用。我只会做super()。\uuuu init\uuuuu(self)
或者在子类中调用它。@Silvio Mayolo这很有意义,谢谢你澄清这一点!我忘了区分类变量和实例变量。