python的__new__方法

1. __new__ 和__init__方法的區(qū)別:

先看一個(gè)例子:

# -*- coding: utf-8 -*-

class Person(object):

    def __new__(cls, name, age):
        print '__new__ called.'
        return super(Person, cls).__new__(cls, name, age)

    def __init__(self, name, age):
        print '__init__ called.'
        self.name = name
        self.age = age

    def __str__(self):
        return '<Person: %s(%s)>' % (self.name, self.age)

if __name__ == '__main__':
    name = Person('xxx', 24)
    print name

當(dāng)實(shí)例化的時(shí)候,結(jié)果:

__new__ called.
__init__ called.
<Person: xxx(24)>

通過(guò)運(yùn)行這段代碼,我們可以看到,new方法的調(diào)用是發(fā)生在init之前的。其實(shí)當(dāng) 你實(shí)例化一個(gè)類的時(shí)候,具體的執(zhí)行邏輯是這樣的:

1.p = Person(name, age)
2.首先執(zhí)行使用name和age參數(shù)來(lái)執(zhí)行Person類的new方法,這個(gè)new方法會(huì) 返回Person類的一個(gè)實(shí)例(通常情況下是使用 super(Persion, cls).new(cls, … …) 這樣的方式),
3.然后利用這個(gè)實(shí)例來(lái)調(diào)用類的init方法,上一步里面new產(chǎn)生的實(shí)例也就是 init里面的的 self
所以,initnew 最主要的區(qū)別在于:

1 .init 通常用于初始化一個(gè)新實(shí)例,控制這個(gè)初始化的過(guò)程,比如添加一些屬性, 做一些額外的操作,發(fā)生在類實(shí)例被創(chuàng)建完以后。它是實(shí)例級(jí)別的方法。

  1. new 通常用于控制生成一個(gè)新實(shí)例的過(guò)程。它是類級(jí)別的方法。
  2. new至少要有一個(gè)參數(shù)cls,代表要實(shí)例化的類,此參數(shù)在實(shí)例化時(shí)由Python解釋器自動(dòng)提供
  3. new必須要有返回值,返回實(shí)例化出來(lái)的實(shí)例,這點(diǎn)在自己實(shí)現(xiàn)new時(shí)要特別注意,可以return父類new出來(lái)的實(shí)例,或者直接是object的new出來(lái)的實(shí)例
  4. 可以將類比作制造商,new方法就是前期的原材料購(gòu)買環(huán)節(jié),init方法就是在有原材料的基礎(chǔ)上,加工,初始化商品環(huán)節(jié)

2. 什么時(shí)候需要__new__

new方法主要是當(dāng)你繼承一些不可變的class時(shí)(比如int, str, tuple), 提供給你一個(gè)自定義這些類的實(shí)例化過(guò)程的途徑。還有就是實(shí)現(xiàn)自定義的metaclass。
具體我們可以用int來(lái)作為一個(gè)例子:
假如我們需要一個(gè)永遠(yuǎn)都是正數(shù)的整數(shù)類型:

class PositiveInteger(int):
    def __init__(self, value):
        super(PositiveInteger, self).__init__(self, abs(value))

i = PositiveInteger(-3)
print i

但運(yùn)行后會(huì)發(fā)現(xiàn),結(jié)果根本不是我們想的那樣,我們?nèi)稳坏玫搅?3。這是因?yàn)閷?duì)于int這種 不可變的對(duì)象,我們只有重載它的new方法才能起到自定義的作用
修改后的代碼:

class PositiveInteger(int):
    def __new__(cls, value):
        return super(PositiveInteger, cls).__new__(cls, abs(value))

i = PositiveInteger(-3)
print i

通過(guò)重載new方法,我們實(shí)現(xiàn)了需要的功能。

3. 單例模式

python的單例模式


可關(guān)注我的個(gè)人公眾號(hào),不定時(shí)分享一些爬蟲案例和技巧


qrcode_for_gh_7dbef0ec6098_258.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔,今天18年5月份再次想寫文章,發(fā)現(xiàn)簡(jiǎn)書還為我保存起的...
    Jenaral閱讀 2,830評(píng)論 2 9
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,762評(píng)論 0 9
  • Scala與Java的關(guān)系 Scala與Java的關(guān)系是非常緊密的!! 因?yàn)镾cala是基于Java虛擬機(jī),也就是...
    燈火gg閱讀 3,480評(píng)論 1 24
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 31,754評(píng)論 18 399
  • 《劉潤(rùn)商學(xué)院》9.20 排中律,自相矛盾,總會(huì)有一個(gè)是對(duì)的。排中律中的反證法‘’反射,歸謬,存真‘’,用來(lái)假設(shè),來(lái)...
    臺(tái)一DDM路靜娟閱讀 585評(píng)論 0 0