【问题标题】:Why not constructor of super class invoked when we declare the object of sub class?为什么在声明子类的对象时不调用超类的构造函数?
【发布时间】:2013-05-19 11:44:38
【问题描述】:

我是一名 Java 程序员,是 Python 编程的初学者。我注意到 python 编程中的意外行为。我期待打印序列为B class ,A Class 构造函数。但它只执行 A 的构造函数。

输出为“它的A的构造函数”,请你帮我理解执行流程。提前致谢

class B:
    def __init__(self):
        print 'Its constructor of B'    

class A(B):
    def __init__(self):
        print 'Its constructor of A'
        #B.__init__(self)

if __name__=='__main__':
    obj=A()

【问题讨论】:

  • 这就是 Python 的工作方式。 IIRC,即使在 Java 中,如果您要扩展其构造函数带有参数的类,则必须显式调用 super(<params>)。唯一的区别是对于不带参数的超类,在 Java 中调用 super() 是可选的,而在 Python 中则必须显式调用它。
  • 显式优于隐式。 python.org/dev/peps/pep-0020

标签: python class python-2.7 constructor


【解决方案1】:

在 python 中,您应该显式调用父级的初始化程序(这就是实际调用 __init__ 方法的方式,-“构造函数”是另外一回事)。

您可以像在注释掉的行中那样进行操作。更好的是,您应该使用 super 函数,该函数会计算出您可以访问哪个父级。它只适用于new-style classes(基本上,这意味着你的类层次结构的根必须继承自object)。

【讨论】:

  • 构造函数和初始化函数有什么区别?好像和我差不多。回答了我自己的问题:init在python数据模型中被称为构造函数表达式:docs.python.org/2/reference/datamodel.html#basic-customization
  • @Voo:很抱歉,您关于构造函数表达式的陈述不正确。根据docs.python.org/2/reference/datamodel.html#basic-customization,构造函数表达式是“对类的调用”。 __init__ 与您在 c++ 和 java 中可能习惯使用的“构造函数”不同,因为它不构造任何东西:类的实例在被调用时已经存在。
  • @Voo:你误解的那句话只是说明__init__ 收到的参数与__new__ 收到的参数相同。
  • @chepner 在那一段中写着As a special constraint on constructors, no value may be returned。这确实引用__new__,因为__new__返回一个对象就很好(实际上相当必要)..
  • @Voo Touché。该文档应该更新。它可能是在 __new__ 可以覆盖之前的日子遗留下来的。 (以下语句需要事实检查:)虽然__init__一直只是一个简单的初始化器,但在1.x版本中,在Python级别没有显式构造函数,因此描述__init__的方式可能很松散。工作。
猜你喜欢
  • 2011-11-02
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 2016-12-12
相关资源
最近更新 更多