__init__()方法是重要的有两个原因。第一个原因是,初始化是最重要的步骤在一个对象的生命周期;每个对象都必须正确地初始化,才能正常工作。第二个原因是,__init__()参数值可以有多种形式。因为有很多方法可以提供参数值__init__(),有很多用例创建对象,我们可以看看其中的一些。我们想要尽可能明确,所以我们需要定义一个初始化正确描述问题域。触摸__init__()方法之前,在任何情况下,我们需要有一个粗略的和简单的观察对象类的层次结构隐含在Python。在这一章,我们看到不同形式的简单对象的初始化(例如:打牌)。之后,我们还可以看更复杂的对象,像手中对象包含集合,包含战略和国家的球员。
这是一个非常简单的类定义和几乎没有做任何事情。我们可以创建一个对象的实例,但我们不能做太多,因为许多特殊的方法容易抛出异常。当我们自定义一个类,对象是超类。下面是类定义的一个例子,它继承了对象与一个新的名字:类X:通过。这里有一些交互定制类:我们可以看到,这个类是一个类类型的对象,和它的基类对象。见每个方法,我们也看看默认行为继承对象。在某些情况下,超类特殊方法的行为就是我们想要的。在其他情况下,我们需要覆盖这个特殊的方法。基类对象的init()方法是基于创建、初始化和销毁。我们推迟先进的特殊方法的创建和销毁以后章节,和目前只专注于初始化。所有类的超类对象__init__()的实现,包括通过默认情况下。
如果没有实现,没有实例变量创建后将创建对象。在某些情况下,这种默认行为是可以接受的。我们总是向对象添加属性,这是基类的子类对象。考虑下面的类,它需要两个实例变量,但不初始化:类矩形:def区域(自我):返回*矩形类都有一个方法,使用两个属性返回一个值。这些属性是没有初始化。这是合法的Python代码。它可以有效地避免专门设置属性,虽然感觉有点奇怪,但有效。以下是与矩形的交互类:104显然这是合法的,但也是混乱的来源,因此它也是我们需要避免的原因。在任何情况下,这种设计提供了很大的灵活性,所以,有时候我们不需要设置中的所有属性__init__()方法。到目前为止,我们已经非常顺利。一个可选属性实际上是一个子类,但不是正式宣布一个子类。
尽管未初始化的属性可能是有用的,他们很可能预示着糟糕的设计。\u201CPython的禅\u201D的建议:\u201C显式优于隐式\u201D。一个__init__()方法应该显式的使用实例变量。可怜的多态性是灵活的和愚蠢的想法。当我们觉得有必要写如下,我们正从边缘的愚蠢的灵活性:如果'x\u201D自我。__dict__:或者尝试:除了AttributeError:是时候重新考虑API,并添加一个常见的方法或属性。重构是更明智的if语句。实现超类的init(),我们初始化对象通过实现__init__()方法。当一个对象被创建时,Python首先创建一个空对象,然后调用__init__()方法的新对象。
以下是卡类定义的层次结构的例子。我们将定义卡超类和三个子类,变异的卡片。两个实例变量直接设定的参数值,并计算了两个变量的初始化方法:卡类:def __init__(自我、等级、套装):=西装=排名,= self._points()类NumberCard(卡):def _points(自我):返回int (), int()类AceCard(卡):def _points(自我):返回1,11类FaceCard(卡):def _points(自我):返回10个,10个在这个例子中,我们提取超类__init__()方法,所以一般在卡初始化父类可以应用到三个子类NumberCard AceCard FaceCard。
每个子类提供了一个独特的_points()方法的实现。所有子类都有相同的特征:他们有相同的方法和属性。这三个子类的对象在一个应用程序中可以互换使用。如果我们使用简单的字符的西装,我们可以创建一个卡的实例如下:卡= [AceCard (' A ', ' ? '), NumberCard (' 2 ', ' ? '), NumberCard (' 3 ', ' ? '))我们列举一些卡片类型,卡值和套装在列表中。从长远来看,我们需要更聪明的工厂函数来创建卡实例;使用这种方法枚举52张牌很无聊而且容易出错。我们联系工厂函数之前,让我们来看看一些其他问题。使用init()来创建显式常量定义西装类卡片。在21点,衣服并不重要,一个简单的字符串。
在许多情况下,物体的一小部分在我们的应用程序可以定义常量的集合。少量的静态对象可能是实现这一战略模式或状态模式的一部分。在某些情况下,我们将有一个恒定的对象池中创建初始化或配置文件,或者我们可以创建常量对象基于命令行参数。我们将初步设计的详细信息和启动设计在16章命令\u201C复制\u201D。Python没有一个简单的和正式的机制来定义一个不可变对象。我们将在第三章相关技术,以确保不变性\u201D属性访问方法属性和描述符\u201D。在这个例子中,是有道理的,衣服是不可变的。下面的类,我们将使用它来创建四个明确的常量:类套装:def __init__(自我、名称、符号):namesymbol常数是由这类:俱乐部,钻石,心,铁锹=套装(\u201C俱乐部\u201D、\u201C?
\u2019),西装(\u2018心\u2019,\u2018?\u2019),西装(\u201C铲\u201D、\u201C?\u201D)现在我们可以通过如下所示的代码片段创建卡片:卡= [AceCard (A,铲)、NumberCard(\u201C2\u201D,铲)、NumberCard(\u201C3\u201D,铲)]这个小例子,这种方法不是一个单一的颜色代码的功能很大的进步。在更复杂的情况下,会有一些策略或国家以这种方式创建的对象。策略或状态设计模式可以更有效的通过重用小,静态常量对象。我们必须承认,这些对象并不是技术上不可变在Python中,它们是可变的。可能会有一些额外的福利编码使这些对象真正不变。
有时令人难以置信的\u201C恶意的程序员\u201D做出调整修改常量值在他们的应用程序。从设计考虑,这是非常愚蠢的。这些令人难以置信的和恶意的程序员不会停止这样做,因为没有更好的方法来用Python代码更加简洁和简单。一个恶意的程序员访问源代码和修改它来编写代码来修改一个常数尽可能容易。最好不要挣扎太久在定义类的不可变的对象。在第三章\u201C访问属性,属性和方法描述符\u201D,我们将展示如何实现不变性在车程序中通过提供适当的诊断信息。