python中类的实例
在下面的代码中,类别B继承自类别A,类别A的变量通过类别B分配。我使用Check1和Check2创建了两个类B的新实例,如下所示:python中类的实例,python,Python,在下面的代码中,类别B继承自类别A,类别A的变量通过类别B分配。我使用Check1和Check2创建了两个类B的新实例,如下所示: class ClassA: def __init__(self, a, b): self.A = a self.B = b class ClassB(ClassA): def __init__(self, a, b): ClassA.A = a ClassA.B =
class ClassA:
def __init__(self, a, b):
self.A = a
self.B = b
class ClassB(ClassA):
def __init__(self, a, b):
ClassA.A = a
ClassA.B = b
def printB(self):
print("B = "+str(ClassA.A + ClassA.B))
if __name__ == '__main__':
print('#### Part I - using Check1 ######')
Check1 = ClassB(1,2)
Check1.printB()
print('#### Part II - Using Check2 ######')
Check2 = ClassB(5,6)
Check2.printB()
print('#### Part III - Again Using Check1 ######')
Check1.printB()
我得到以下输出:
#### Part I - using Check1 ######
B = 3
#### Part II - Using Check2 ######
B = 11
#### Part III - Again Using Check1 ######
B = 11
我的问题是,为什么在调用第三部分中的检查1时会得到B=11?python不应该为Check1对象创建一个新的父类实例,并且Check1不应该将输出显示为B=3
如何修改上述代码,以便在第三部分调用时,Check1的值为B=3?您似乎觉得Python对象的每个类都有单独的实例变量名称空间,或者Python对象有C++风格的基类子对象。Python不是这样工作的 创建
ClassB
的实例时,您只创建一个对象,即ClassA
和ClassB
的实例。没有单独的ClassA
实例。当您的ClassB.\uuuuu init\uuuuu
执行
ClassA.A = a
ClassA.B = b
这并不意味着“设置ClassA中声明的实例变量”,或“在附加到此对象的ClassA的某个实例上设置实例变量”。此行指定给ClassA
上的类变量,而不是任何对象上的实例变量。(另外,您从未委托给超类构造函数,因此ClassA.\uuuu init\uuuu
被完全跳过。)
类变量是全局状态-单独的实例不会获得单独的副本。创建Check2
将覆盖创建Check1
时设置的值
看起来您想要从
ClassB
的构造函数中获得的行为正是ClassA
的构造函数的行为,因此您可以直接继承\uuuuu init\uuuu
。您不需要编写单独的\uuuuu init\uuuu
对于需要访问实例变量的printB
:
class ClassB(ClassA):
def printB(self):
print("B = "+str(self.A + self.B))
您似乎觉得Python对象的每个类都有单独的实例变量名称空间,或者Python对象有C++风格的基类子对象。Python不是这样工作的 创建
ClassB
的实例时,您只创建一个对象,即ClassA
和ClassB
的实例。没有单独的ClassA
实例。当您的ClassB.\uuuuu init\uuuuu
执行
ClassA.A = a
ClassA.B = b
这并不意味着“设置ClassA中声明的实例变量”,或“在附加到此对象的ClassA的某个实例上设置实例变量”。此行指定给ClassA
上的类变量,而不是任何对象上的实例变量。(另外,您从未委托给超类构造函数,因此ClassA.\uuuu init\uuuu
被完全跳过。)
类变量是全局状态-单独的实例不会获得单独的副本。创建Check2
将覆盖创建Check1
时设置的值
看起来您想要从
ClassB
的构造函数中获得的行为正是ClassA
的构造函数的行为,因此您可以直接继承\uuuuu init\uuuu
。您不需要编写单独的\uuuuu init\uuuu
对于需要访问实例变量的printB
:
class ClassB(ClassA):
def printB(self):
print("B = "+str(self.A + self.B))
您没有正确实现继承——分配给
ClassA
的成员将覆盖类对象iself,而不是继承的实例属性(仍然可以通过self
访问)。此外,您不希望复制和粘贴父构造函数;相反,你应该直接给它打电话
class ClassA:
def __init__(self, a, b):
self.A = a
self.B = b
class ClassB(ClassA):
def __init__(self, a, b):
ClassA.__init__(self, a, b)
def printB(self):
print("B = "+str(self.A + self.B))
您没有正确实现继承——分配给
ClassA
的成员将覆盖类对象iself,而不是继承的实例属性(仍然可以通过self
访问)。此外,您不希望复制和粘贴父构造函数;相反,你应该直接给它打电话
class ClassA:
def __init__(self, a, b):
self.A = a
self.B = b
class ClassB(ClassA):
def __init__(self, a, b):
ClassA.__init__(self, a, b)
def printB(self):
print("B = "+str(self.A + self.B))
您在
ClassB
的\uuuu init\uuuu
方法中尝试做的事情,super()
可以为您做(而且您所做的事情并不像其他人指出的那样正确)。这样,您就不必重复代码,只能在基类中初始化属性:
class ClassA:
def __init__(self, a, b):
self.A = a
self.B = b
class ClassB(ClassA):
def __init__(self, a, b):
super().__init__(a=a, b=b)
def printB(self):
print("B = "+str(self.A + self.B))
以及输出:
Check1 = ClassB(1,2)
Check1.printB()
B = 3
Check2 = ClassB(5,6)
Check2.printB()
B = 11
Check1.printB()
B = 3
您在
ClassB
的\uuuu init\uuuu
方法中尝试做的事情,super()
可以为您做(而且您所做的事情并不像其他人指出的那样正确)。这样,您就不必重复代码,只能在基类中初始化属性:
class ClassA:
def __init__(self, a, b):
self.A = a
self.B = b
class ClassB(ClassA):
def __init__(self, a, b):
super().__init__(a=a, b=b)
def printB(self):
print("B = "+str(self.A + self.B))
以及输出:
Check1 = ClassB(1,2)
Check1.printB()
B = 3
Check2 = ClassB(5,6)
Check2.printB()
B = 11
Check1.printB()
B = 3
您正在为clsss变量而不是对象变量赋值。您需要在类B的init中创建类A的实例,然后在
ClassB
构造函数中分配类变量(不是实例变量)。无论您上次传递的值是什么,现在都由整个类共享。这里只有一个ClassA
。对ClassA.A的每个引用(例如)都指向完全相同的class属性。您将值分配给clsss变量,而不是对象变量。您需要在类B的init中创建类A的实例,然后在ClassB
构造函数中分配类变量(不是实例变量)。无论您上次传递的值是什么,现在都由整个类共享。这里只有一个ClassA
。对ClassA.A
(例如)的每个引用都指向完全相同的class属性。