1. 程式人生 > >python設計模式-單例模式

python設計模式-單例模式

單例模式

(一)什麼是單例模式

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

(二)實現單例的方法

  • 匯入模組
  • 使用new方法
  • 使用裝飾器

(三)模組

Python 模組在第一次匯入時,會生成 .pyc 檔案,當第二次匯入時,就會直接載入 .pyc 檔案,而不會再次執行模組程式碼。因此,我們只需把相關的函式和資料定義在一個模組中,就可以獲得一個單例物件了。

(四)new方法

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

__author__ = 'loco_python'


class Person(object):
    _instance = None
    _is_init = False
    # 實現單例模式
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            # 如果沒有建立物件,我們就建立物件
            cls._instance = super(Person, cls).__new__(cls, *args, **kwargs)
        # 無論如何我們只返回一個物件
return cls._instance # 只做一次初始化。 def __init__(self, name, age): if not self._is_init: self.name = name self.age = age self._is_init = True def __str__(self): return self.name p1 = Person('xiaohua', 18) p2 = Person('xiaowang', 19
) # p1和p2同一地址 print id(p1), id(p2) # 4308349264 4308349264 # 只初始化了第一次 print p1, p2 # xiaohua xiaohua
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

(五)裝飾器

__author__ = 'loco_python'

from functools import wraps


def singleton(cls):
    _instance = {}
    @wraps(cls)
    def wrapper(*args, **kwargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kwargs)
        return _instance[cls]
    return wrapper

@singleton
class Person:
    def __init__(self):
        pass

p = Person()
p1 = Person()
print id(p), id(p1)   # 4501461760 4501461760
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
            </div>

單例模式

(一)什麼是單例模式

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

(二)實現單例的方法

  • 匯入模組
  • 使用new方法
  • 使用裝飾器

(三)模組

Python 模組在第一次匯入時,會生成 .pyc 檔案,當第二次匯入時,就會直接載入 .pyc 檔案,而不會再次執行模組程式碼。因此,我們只需把相關的函式和資料定義在一個模組中,就可以獲得一個單例物件了。

(四)new方法

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

__author__ = 'loco_python'


class Person(object):
    _instance = None
    _is_init = False
    # 實現單例模式
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            # 如果沒有建立物件,我們就建立物件
            cls._instance = super(Person, cls).__new__(cls, *args, **kwargs)
        # 無論如何我們只返回一個物件
        return cls._instance

    # 只做一次初始化。
    def __init__(self, name, age):
        if not self._is_init:
            self.name = name
            self.age = age
            self._is_init = True

    def __str__(self):
        return self.name

p1 = Person('xiaohua', 18)
p2 = Person('xiaowang', 19)
# p1和p2同一地址
print id(p1), id(p2)  # 4308349264 4308349264
# 只初始化了第一次
print p1, p2     # xiaohua xiaohua  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

(五)裝飾器

__author__ = 'loco_python'

from functools import wraps


def singleton(cls):
    _instance = {}
    @wraps(cls)
    def wrapper(*args, **kwargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kwargs)
        return _instance[cls]
    return wrapper

@singleton
class Person:
    def __init__(self):
        pass

p = Person()
p1 = Person()
print id(p), id(p1)   # 4501461760 4501461760
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
            </div>