最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳細(xì)解讀Python中的__init__()方法

 更新時(shí)間:2015年05月02日 11:57:33   作者:young_ipython  
這篇文章主要介紹了Python中的__init__()方法,__init__()方法是Python學(xué)習(xí)當(dāng)中重要的基礎(chǔ)知識(shí),需要的朋友可以參考下

__init__()方法意義重大的原因有兩個(gè)。第一個(gè)原因是在對(duì)象生命周期中初始化是最重要的一步;每個(gè)對(duì)象必須正確初始化后才能正常工作。第二個(gè)原因是__init__()參數(shù)值可以有多種形式。

因?yàn)橛泻芏喾N方式為__init__()提供參數(shù)值,對(duì)于對(duì)象創(chuàng)建有大量的用例,我們可以看看其中的幾個(gè)。我們想盡可能的弄清楚,因此我們需要定義一個(gè)初始化來正確的描述問題區(qū)域。

在我們接觸__init__()方法之前,無論如何,我們都需要粗略、簡(jiǎn)單地看看在Python中隱含的object類的層次結(jié)構(gòu)。

在這一章,我們看看不同形式的簡(jiǎn)單對(duì)象的初始化(例如:打牌)。在這之后,我們還可以看看更復(fù)雜的對(duì)象,就像包含集合的hands對(duì)象以及包含策略和狀態(tài)的players。
隱含的超類——object

每一個(gè)Python類都隱含了一個(gè)超類:object。它是一個(gè)非常簡(jiǎn)單的類定義,幾乎不做任何事情。我們可以創(chuàng)建object的實(shí)例,但是我們不能用它做太多,因?yàn)樵S多特殊的方法容易拋出異常。

當(dāng)我們自定義一個(gè)類,object則為超類。下面是一個(gè)類定義示例,它使用新的名稱簡(jiǎn)單的繼承了object:

class X:
  pass

下面是和自定義類的一些交互:

>>> X.__class__
<class 'type'>
>>> X.__class__.__base__
<class 'object'>

我們可以看到該類是type類的一個(gè)對(duì)象,且它的基類為object。

就像在每個(gè)方法中看到的那樣,我們也看看從object繼承的默認(rèn)行為。在某些情況下,超類特殊方法的行為是我們所想要的。在其他情況下,我們需要覆蓋這個(gè)特殊方法。
基類對(duì)象的init()方法

對(duì)象生命周期的基礎(chǔ)是創(chuàng)建、初始化和銷毀。我們將創(chuàng)建和銷毀的高級(jí)特殊方法推遲到后面的章節(jié)中,目前只關(guān)注初始化。

所有類的超類object,有一個(gè)默認(rèn)包含pass的__init__()實(shí)現(xiàn),我們不需要去實(shí)現(xiàn)__init__()。如果不實(shí)現(xiàn)它,則在對(duì)象創(chuàng)建后就不會(huì)創(chuàng)建實(shí)例變量。在某些情況下,這種默認(rèn)行為是可以接受的。

我們總是給對(duì)象添加屬性,該對(duì)象為基類object的子類。思考以下類,需要兩個(gè)實(shí)例變量但不初始化它們:

class Rectangle:
  def area(self):
    return self.length * self.width

Rectangle類有一個(gè)使用兩個(gè)屬性來返回一個(gè)值的方法。這些屬性沒有初始化。這是合法的Python代碼。它可以有效的避免專門設(shè)置屬性,雖然感覺有點(diǎn)奇怪,但是有效。

下面是于Rectangle類的交互:

>>> r = Rectangle()
>>> r.length, r.width = 13, 8
>>> r.area()
104

顯然這是合法的,但也是容易混淆的根源,所以也是我們需要避免的原因。

無論如何,這個(gè)設(shè)計(jì)給予了很大的靈活性,這樣有時(shí)候我們不用在__init__()方法中設(shè)置所有屬性。至此我們走的很順利。一個(gè)可選屬性其實(shí)就是一個(gè)子類,只是沒有真正的正式聲明為子類。我們創(chuàng)建多態(tài)在某種程度上可能會(huì)引起混亂以及if語句的不恰當(dāng)使用所造成的盤繞。雖然未初始化的屬性可能是有用的,但很有可能是糟糕設(shè)計(jì)的前兆。

《Python之禪》中的建議:

    "顯式比隱式更好。"

一個(gè)__init__()方法應(yīng)該讓實(shí)例變量顯式。

可憐的多態(tài)

靈活和愚蠢就在一念之間。

當(dāng)我們覺得需要像下面這樣寫的時(shí)候,我們正從靈活的邊緣走向愚蠢:

if 'x' in self.__dict__:

或者:

try:
  self.x
except AttributeError:

是時(shí)候重新考慮API并添加一個(gè)通用的方法或?qū)傩?。重?gòu)比添加if語句更明智。
在超類中實(shí)現(xiàn)init()

我們通過實(shí)現(xiàn)__init__()方法來初始化對(duì)象。當(dāng)一個(gè)對(duì)象被創(chuàng)建,Python首先創(chuàng)建一個(gè)空對(duì)象,然后為那個(gè)新對(duì)象調(diào)用__init__()方法。這個(gè)方法函數(shù)通常用來創(chuàng)建對(duì)象的實(shí)例變量并執(zhí)行任何其他一次性處理。

下面是Card類示例定義的層次結(jié)構(gòu)。我們將定義Card超類和三個(gè)子類,這三個(gè)子類是Card的變種。兩個(gè)實(shí)例變量直接由參數(shù)值設(shè)置,兩個(gè)變量通過初始化方法計(jì)算:

class Card:
  def __init__(self, rank, suit):
    self.suit = suit
    self.rank = rank
    self.hard, self.soft = self._points()

class NumberCard(Card):
  def _points(self):
    return int(self.rank), int(self.rank)

class AceCard(Card):
  def _points(self):
    return 1, 11

class FaceCard(Card):
  def _points(self):
    return 10, 10

在這個(gè)示例中,我們提取__init__()方法到超類,這樣在Card超類中的通用初始化可以適用于三個(gè)子類NumberCard、AceCard和FaceCard。

這是一種常見的多態(tài)設(shè)計(jì)。每一個(gè)子類都提供一個(gè)唯一的_points()方法實(shí)現(xiàn)。所有子類都有相同的簽名:有相同的方法和屬性。這三個(gè)子類的對(duì)象在一個(gè)應(yīng)用程序中可以交替使用。

如果我們?yōu)榛ㄉ褂煤?jiǎn)單的字符,我們可以創(chuàng)建Card實(shí)例,如下所示:

cards = [AceCard('A', '?'), NumberCard('2','?'), NumberCard('3','?'),]

我們?cè)诹斜碇忻杜e出一些牌的類、牌值和花色。從長(zhǎng)遠(yuǎn)來說,我們需要更智能的工廠函數(shù)來創(chuàng)建Card實(shí)例;用這個(gè)方法枚舉52張牌無聊且容易出錯(cuò)。在我們接觸工廠函數(shù)之前,我們看一些其他問題。
使用init()創(chuàng)建顯式常量

可以給牌定義花色類。在二十一點(diǎn)中,花色無關(guān)緊要,簡(jiǎn)單的字符串就可以。

我們使用花色構(gòu)造函數(shù)作為創(chuàng)建常量對(duì)象的示例。在許多情況下,我們應(yīng)用中小部分對(duì)象可以通過常量集合來定義。小部分的靜態(tài)對(duì)象可能是實(shí)現(xiàn)策略模式或狀態(tài)模式的一部分。

在某些情況下,我們會(huì)有一個(gè)在初始化或配置文件中創(chuàng)建的常量對(duì)象池,或者我們可以基于命令行參數(shù)創(chuàng)建常量對(duì)象。我們會(huì)在第十六章《通過命令進(jìn)行復(fù)制》中獲取初始化設(shè)計(jì)和啟動(dòng)設(shè)計(jì)的詳細(xì)信息。

Python沒有簡(jiǎn)單正式的機(jī)制來定義一個(gè)不可變對(duì)象,我們將在第三章《屬性訪問、方法屬性和描述符》看看保證不可變性的相關(guān)技術(shù)。在本示例中,花色不可變是有道理的。

下面這個(gè)類,我們將用于創(chuàng)建四個(gè)顯式常量:

class Suit:
  def __init__(self, name, symbol):
    self.name= name
    self.symbol= symbol

下面是通過這個(gè)類創(chuàng)建的常量:

Club, Diamond, Heart, Spade = Suit('Club','?'), Suit('Diamond','?'), Suit('Heart','?'), Suit('Spade','?')

現(xiàn)在我們可以通過下面展示的代碼片段創(chuàng)建cards:

cards = [AceCard('A', Spade), NumberCard('2', Spade), NumberCard('3', Spade),]

這個(gè)小示例,這種方法對(duì)于單個(gè)特性的花色代碼來說并不是一個(gè)巨大的進(jìn)步。在更復(fù)雜的情況下,會(huì)有一些策略或狀態(tài)對(duì)象通過這個(gè)方式創(chuàng)建。通過從小的、靜態(tài)的常量對(duì)象中復(fù)用可以使策略或狀態(tài)設(shè)計(jì)模式更有效率。

我們必須承認(rèn),在Python中這些對(duì)象并不是技術(shù)上一成不變的,它是可變的。進(jìn)行額外的編碼使得這些對(duì)象真正不變可能會(huì)有一些好處。

無關(guān)緊要的不變性

不變性很有吸引力但卻容易帶來麻煩。有時(shí)候被神話般的“惡意程序員”在他們的應(yīng)用程序中通過修改常量值進(jìn)行調(diào)整。從設(shè)計(jì)上考慮,這是非常愚蠢的。這些神話般的、惡意的程序員不會(huì)停止這樣做,因?yàn)橐呀?jīng)沒有更好的方法去更簡(jiǎn)潔簡(jiǎn)單的在Python中編碼。惡意程序員訪問到源碼并且修改它僅僅是希望盡可能輕松地編寫代碼來修改一個(gè)常數(shù)。

在定義不可變對(duì)象的類的時(shí)候最好不要掙扎太久。在第三章《屬性訪問、方法屬性和描述符》中,我們將通過在有bug的程序中提供合適的診斷信息來展示如何實(shí)現(xiàn)不變性。

相關(guān)文章

最新評(píng)論

萍乡市| 台东县| 库尔勒市| 兰考县| 井陉县| 治县。| 保康县| 布拖县| 仁布县| 云林县| 肥西县| 马边| 长阳| 肃北| 承德县| 河南省| 黄梅县| 淮北市| 巴南区| 定边县| 武宁县| 鹤山市| 阳信县| 聂荣县| 两当县| 晋中市| 许昌县| 康平县| 教育| 廊坊市| 桃园市| 灵台县| 邹平县| 南皮县| 襄汾县| 大英县| 德兴市| 海原县| 舒兰市| 晋中市| 徐州市|