1. 程式人生 > 程式設計 >Python 用__new__方法實現單例的操作

Python 用__new__方法實現單例的操作

介紹

init 方法通常用在初始化一個類例項時候,但其實它不是例項化一個類的時候第一個被呼叫 的方法。當使用 Student(id,name) 這樣的表示式來例項化一個類時,最先被呼叫的方法 其實是 new 方法。

new方法接受的引數雖然也是和init一樣,但init是在類例項建立之後呼叫,而 new方法正是建立這個類例項的方法。

new為物件分配空間,是內建的靜態方法,new在記憶體中為物件分配了空間也返回了物件的引用,init獲得了這個引用才初始化這個例項。

示例

一個非常簡單的單例

class A:
 instance = None
 def __new__(cls,*args,**kwargs):
  if cls.instance is None:
   cls.instance = super().__new__(cls)
  return cls.instance

因為new方法是一個靜態方法(也就是在定義的時候就沒有cls引數),所以在這裡要傳入一個cls引數,而且這裡的new你改造過了,所以要返回爸爸的new方法。

按造這個方法改造的單例怎麼new都是同一個例項,但init仍然會被執行多次,也就是建立了幾個物件就呼叫幾次初始化方法。所以還要對init再進行一些判斷。

class A:
 instance = None
 init_flag = False # 初始化標記

 def __new__(cls,**kwargs):
  if cls.instance is None:
   cls.instance = super().__new__(cls)
  return cls.instance

 def __init__(self):
  if A.init_flag:
   return
  print('執行了初始化方法')
  A.init_flag = True

if __name__ == '__main__':
 a = A()
 b = A()
 print(a)
 print(b)

輸出結果:

執行了初始化方法

<main.A object at 0x00000210E6F09320>

<main.A object at 0x00000210E6F09320>

總結

通過過載new方法,可以比較簡單地實現單例,Python還有很多有趣的內建函式,有空可以再研究研究。

補充知識:Python餓漢式和懶漢式單例模式的實現

看程式碼吧~

# 餓漢式
class Singleton(object):
 # 重寫建立例項的__new__方法
 def __new__(cls):
  # 如果類沒有例項屬性,進行例項化,否則返回例項
  if not hasattr(cls,'instance'):
   cls.instance = super(Singleton,cls).__new__(cls)
  return cls.instance

餓漢式在建立的時候就會生成例項

# 懶漢式
class Singleton(object):
 __instance = None
 def __init__(self):
  if not self.__instance:
   print('呼叫__init__, 例項未建立')
  else:
   print('呼叫__init__,例項已經建立過了:',__instance)

 @classmethod
 def get_instance(cls):
  # 呼叫get_instance類方法的時候才會生成Singleton例項
  if not cls.__instance:
   cls.__instance = Singleton()
  return cls.__instance

以上這篇Python 用__new__方法實現單例的操作就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。