python單列模式

2021-09-19 12:07:04 字數 4207 閱讀 8570

單例模式(singleton pattern)是一種常用的軟體設計模式,該模式的主要目的是確保某乙個類只有乙個例項存在。當你希望在整個系統中,某個類只能出現乙個例項時,單例物件就能派上用場。

單例模式的要點有三個;一是某個類只能有乙個例項;二是它必須自行建立這個例項;三是它必須自行向整個系統提供這個例項。

在 python 中,我們可以用多種方法來實現單例模式:

使用模組

使用new

使用裝飾器(decorator)

使用元類(metaclass)

1.使用模組

如果我們真的想要乙個單例類,可以考慮這樣做:

#tests1.py

class myclass(object):

def foo(self):

print(『myclass.foo』)

my_class_obj=myclass()

將上面的**儲存在檔案 tests1.py 中,然後這樣使用:

from .tests1 import my_class_obj

my_class_obj.foo()

這種方法相當於把乙個類寫成乙個例項化模組,無論你什麼時候呼叫,都是那乙個例項,所以就算乙個單列了

2.使用__new__函式

為了使類只能出現乙個例項,我們可以使用new來控制例項的建立過程,**如下:12

3456

789class myclass(object):

_instance = none

defnew(cls, *args, **kwargs):

if not cls._instance:

cls._instance = super(myclass, cls).new(cls, *args, **kwargs)

return cls._instance

class herclass(myclass):

a = 1

在上面的**中,我們將類的例項和乙個類變數 _instance 關聯起來,如果 cls._instance 為 none 則建立例項,否則直接返回 cls._instance。

執**況如下:=

one = herclass()

two = herclass()

print(one == two) #true

print(one is two) #true

print(id(one), id(two)) #42818864 42818864

3. 使用裝飾器

我們知道,裝飾器(decorator)可以動態地修改乙個類或函式的功能。這裡,我們也可以使用裝飾器來裝飾某個類,使其只能生成乙個例項,**如下:

from functools import wraps

def singleton(cls):

instances = {}

@wraps(cls)

def getinstance(*args, **kwargs):

if cls not in instances:

instances[cls] = cls(*args, **kwargs)

return instances[cls]

return getinstance

@singleton

class myclass(object):

a = 1

在上面,我們定義了乙個裝飾器 singleton,它返回了乙個內部函式 getinstance,該函式會判斷某個類是否在字典 instances 中,如果不存在,則會將 cls 作為 key,cls(*args, **kw) 作為 value 存到 instances 中,否則,直接返回 instances[cls]。

4. 使用 metaclass

元類(metaclass)可以控制類的建立過程,它主要做三件事:

1.攔截類的建立

2.修改類的定義

3.返回修改後的類

使用元類實現單例模式的**如下:

class singleton(type):

_instances = {}

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

if cls not in cls._instances:

cls._instances[cls] = super(singleton, cls).__call__(*args, **kwargs)

return cls._instances[cls]

class myclass(metaclass=singleton):

pass

優點:

一、例項控制

單例模式會阻止其他物件例項化其自己的單例物件的副本,從而確保所有物件都訪問唯一例項。

二、靈活性

因為類控制了例項化過程,所以類可以靈活更改例項化過程。

缺點:

一、開銷

雖然數量很少,但如果每次物件請求引用時都要檢查是否存在類的例項,將仍然需要一些開銷。可以通過使用靜態初始化解決此問題。

二、可能的開發混淆

使用單例物件(尤其在類庫中定義的物件)時,開發人員必須記住自己不能使用 new關鍵字例項化物件。因為可能無法訪問庫源**,因此應用程式開發人員可能會意外發現自己無法直接例項化此類。

三、物件生存期

不能解決刪除單個物件的問題。在提供記憶體管理的語言中(例如基於.net framework的語言),只有單例類能夠導致例項被取消分配,因為它包含對該例項的私有引用。在某些語言中(如 c++),其他類可以刪除物件例項,但這樣會導致單例類**現懸浮引用。

類也是物件

只要你使用關鍵字class,python直譯器在執行的時候就會建立乙個物件。

下面的**段:

class myclass(object):

pass

print(myclass) # 你可以列印乙個類,因為它其實也是乙個物件

#def echo(o):

print(o)

echo(myclass) # 你可以將類做為引數傳給函式

myclass.new_attribute = 『foo』 # 你可以為類增加屬性

print(hasattr(myclass,『new_attribute』)) #true

print(myclass.new_attribute) #foo

myclassmirror=myclass    # 你可以將類賦值給乙個變數

print(myclassmirror())

<main.myclass object at 0x00000000028cde10>

動態地建立類

因為類也是物件,你可以在執行時動態的建立它們,就像其他任何物件一樣。首先,你可以在函式中建立類,使用class關鍵字即可

def choose_class(name):

if name == 『foo』:

class foo(object):

pass

return foo # 返回的是類,不是類的例項

else:

class bar(object):

pass

return bar
myclass = choose_class(『foo』)

print(myclass) # 函式返回的是類,不是類的例項

print(myclass()) # 你可以通過這個類建立類例項,也就是物件

<main.choose_class..foo object at 0x00000000021e5cf8>

但這還不夠動態。

由於類也是物件,所以它們必須是通過什麼東西來生成的才對。

還記得內建函式type嗎?這個古老但強大的函式能夠讓你知道乙個物件的型別是什麼,就像這樣:

print(type(1)) #

print(type(『1』)) #

print(type(myclass)) #

print(type(myclass())) #

python單列模式 Python單列模式

實現單例模式的幾種方式 1.使用模組 2.使用裝飾器 3.使用類 4.基於 new 方法實現 推薦使用,方便 5.基於metaclass方式實現 單例模式 singleton pattern 是一種常用的軟體設計模式,該模式的主要目的是確保某乙個類只有乙個例項存在。當你希望在整個系統中,某個類只能出...

Python 物件導向 單列模式

1 什麼是單例模式 乙個類有且只能建立乙個物件空間,目的是為了節約記憶體資源 例如 站 資料庫操作類 只需要乙個物件就能完成所有的功能,沒有必要建立多個物件浪費記憶體資源.2.實現單例模式 class singleton object 類屬性 instance none isinit false 是...

Python 裝飾器實現單列模式

使用裝飾器實現單列模式 defsingleton cls 用來存在例項的字典 singleton instance 判斷字典中是否例項 ifnot singleton instance.get cls.name 沒有則建立乙個例項,並存入字典中 singleton instance cls.name...