1. 程式人生 > >python3面向物件(4)之__new__方法和__init__方法

python3面向物件(4)之__new__方法和__init__方法

1.簡單來說__new__方法和__init__方法都是類中的內建方法;這兩個方法再例項化物件的時候會被自動呼叫;

2.__new__方法的呼叫在 __init__方法之前;

3.__new__方法中有個引數:cls   ;  __init__方法中有個引數是self  

4.__new__方法的作用是:(1)為例項化物件分配一個空間(2)返回這個物件的引用

5.__init__方法的作用是對這個例項化物件再次加工;self指的就是這個例項化物件

看程式碼:

class MusicPlayer(object):    #建立一個音樂播放器

    def __new__(cls, *args, **kwargs):

        print("建立物件,分配空間")    # 1. 建立物件時,new方法會被自動調     
        instance = super().__new__(cls)   # 2. 為物件分配空間
        return instance   # 3. 返回物件的引用,必須的有這個返回,不然self找不到物件

    def __init__(self,name):   #初始化方法;對這個例項化物件再次加工
     self.name = name print("播放器初始化") # 建立播放器物件 player = MusicPlayer("小米") print(player)

 做個不是很恰當的比喻(暫時想到的這個);類就好比一張大樓的圖紙;我們要按著這個圖紙去建大樓;而__new__方法就好比建造這個大樓的地址,你是要在北京蓋樓還是上海蓋樓,必須有個明確的地址,而__init__方法就好比;有了圖紙和地方就開始建樓吧。

二通過__new__方法實現單例模式

首先要明白什麼是單例模式:簡單理解就是一個類只能建立一個例項物件(還用上面這個比喻,就是說我們這個開發商比較小,只能拿到一塊地皮;當我們第一次用這塊地蓋了樓,又想蓋第二棟沒有地皮怎麼辦啊,簡單把把上次蓋好的拆掉就又地方了啊)

看程式碼:

class MusicPlayer(object):

    def __new__(cls, *args, **kwargs):

        # 1. 建立物件時,new方法會被自動呼叫
        print("建立物件,分配空間")

        # 2. 為物件分配空間
        instance = super().__new__(cls)

        # 3. 返回物件的引用
        return instance

    def __init__(self):
        print("播放器初始化")


# 建立播放器物件
player1 = MusicPlayer()
player2 = MusicPlayer()

print(id(player1))
print(id(player2))

 列印結果:這是一個正常的例項化物件;建立了兩個物件;這兩個物件的ID是不一樣的

建立物件,分配空間
播放器初始化
建立物件,分配空間
播放器初始化
2525789450312
2525789421464

 單例模式:

class MusicPlayer(object):
    instance = None      #定義一個類屬性為None
    def __new__(cls, *args, **kwargs):

        # 1. 建立物件時,new方法會被自動呼叫
        print("建立物件,分配空間")
        if cls.instance is None:  #如果這個類屬性為None就為這個物件分配一個空間
            # 2. 為物件分配空間
            cls.instance = super().__new__(cls)

        # 3. 返回物件的引用
        return cls.instance  #否則返回上一個物件空間

    def __init__(self):
        print("播放器初始化")


# 建立播放器物件
player1 = MusicPlayer()
player2 = MusicPlayer()

print(id(player1))
print(id(player2))

 結果:

建立物件,分配空間
播放器初始化
建立物件,分配空間
播放器初始化
2300636655688
2300636655688

 那麼建立的兩個例項化物件的id就一樣了