1.2 基类中的init()方法

    对象的生命周期主要包括了创建、初始化和销毁。后面章节会详细讨论对象的创建和销毁,本章专注于对象的初始化。

    object作为所有类的基类,已经为init()方法提供了默认实现,一般情况下不需要重写这个函数。如果没有对它进行重写,那么在创建对象时将不会产生其他变量的实例。在某些情况下,这种默认行为是可以接受的。

    对于继承自object的子类,总可以对它的属性进行扩展。例如,对于下面这个类,实例化就不对函数(area)所需要的变量(widthlength)进行初始化。

    class Rectangle:
      def area( self ):
        return self.length * self.width
    Rectangle类的area函数在返回值时使用了两个属性,可并没有在任何地方对其赋值。在Python中,这种看似奇怪的调用尚未赋值属性的操作却是合法的。 下面这段代码演示如何使用刚定义的Rectangle类。
    >>> r= Rectangle()
    >>> r.length, r.width = 13, 8
    >>>r.area()
    104
    虽然这种延迟赋值的实现方式在Python中是合法的,但是却给调用者带来了潜在的困惑,因此要尽量避免这样的用法。 然而,这样的设计看似又提供了灵活性,意味着在init()方法被调用时不必为所有的属性赋值。这看似是不错的选择,一个可选属性即可以看作是某子类中的成员,且无须对这个子类进行显式地定义就可以完成对原生机制的扩展。然而这种多态机制不但给程序带来了隐藏的不确定性,也会相应产生很多令人费解的if语句。 因此,延迟初始化属性的设计在某种情形下可能会有用,可是这样也可能会导致非常糟糕的设计。 在Zen of python poem一书中曾提出过这样的建议: “显式而非隐式”。 对于每个init()方法,都应当显式地指定要初始化的变量。
    糟糕的多态 在灵活性与糟糕之间有一个临界。 一旦发觉书写了这样的代码,我们就已经丧失了灵活性并开始了糟糕的设计。   if 'x' in self.dict:

    或:

      try:     self.x  except AttributeError:

    这时就要考虑添加一个公共函数或属性来重构这个API,相比于添加if语句,重构将是更好的选择。