我们在浏览别人的代码,有的时候遇到
super(NeuralNetwork, self).__init__()
,也有的时候遇到什么都没有的情况,如super().__init__()
,这二者究竟有什么区别呢?
super(NeuralNetwork, self).__init__()
和super().__init__()
的区别在于第一个版本指定了当前类NeuralNetwork
,作为调用的方法所属的类,而后者则使用了当前类的默认值,即self.__class__
,这两种方式在绝大多数情况下是等效的。
使用super()
函数可以调用父类的方法,从而避免硬编码父类名称,这有助于提高代码的可维护性和可重用性。在 Python 3.x 中,可以省略 super() 中的参数,因为它们会自动检测当前类和实例。所以,如果你的代码运行在 Python 3.x 中,你可以只使用super().__init__()
调用父类的构造函数。
什么是硬编码?💓
其定义也就是“将可变变量用一个固定数值表示”,这种方式在编码的过程中会导致变量很难修改。
在编程中,硬编码是指将值或行为直接嵌入代码中,而不是使用参数或配置文件来指定它们。如果在代码中硬编码了父类的名称,则在子类继承结构发生更改时,可能需要修改代码,以便在子类中调用正确的父类方法。这样的代码往往更难以维护和扩展,因为它需要手动进行修改,而不是自动适应更改。
class Parent:
def __init__(self):
print('Parent init')
class Child(Parent):
def __init__(self):
Parent.__init__(self)
print('Child init')
在 Child 类中,调用 Parent 类的构造函数时,硬编码了 Parent 类的名称。如果我们稍后更改 Child 类的基类,这段代码就会出现问题,例如:
class GrandParent:
def __init__(self):
print('GrandParent init')
class Child(GrandParent):
def __init__(self):
Parent.__init__(self) # 现在有问题
print('Child init')
这个例子中,因为 Child 类的基类已经更改为 GrandParent,因此调用 Parent 类的构造函数是错误的。我们必须手动修改代码以反映这个更改,这是一个非常不便的过程。
相比之下,使用 super() 函数可以避免硬编码父类名称,例如:
class Parent:
def __init__(self):
print('Parent init')
class Child(Parent):
def __init__(self):
super().__init__()
print('Child init')
这个例子中,我们使用 super() 函数来调用父类的构造函数,而不是硬编码 Parent 类的名称。因此,在更改 Child 类的父类时,我们不需要修改代码,因为 super() 函数会自动调用正确的父类构造函数。