函式裝飾器和類裝飾器實現單例類

2021-10-03 13:44:01 字數 2273 閱讀 8753

單例類,指的是這個類只能建立乙個例項,建立完成後,其他類例項都無法再建立。今天我們來看一下,使用函式裝飾器和類裝飾器怎麼實現這種特殊一點的類。

裝飾器算是類裡面比較難的內容之一,但是實際上它的思想並不複雜。簡單點說,就是在你原來內容的基礎上,在外面給你加點東西,實現類似裝飾的效果。但是它是怎麼實現的呢?一般來說,都是通過攔截函式呼叫來實現的,比如:用裝飾器裝飾函式的時候,它攔截函式呼叫,裝飾類的時候,它攔截類例項的建立呼叫,即攔截類初始化__init__函式。

知道這個原理以後,我們就可以來嘗試實現了。

首先來看通過函式裝飾器攔截類的建立過程,**如下:

instance = {}

def createinstance(cls, *args):

if cls not in instance:

instance[cls] = cls(*args)

return instance[cls]

def singleins(cls):

def oncall(*args):

return createinstance(cls, *args)

return oncall

上面就是這個函式裝飾器singleins的實現,它返回乙個函式呼叫,當用它來裝飾乙個類,建立類例項的時候,就會用oncall方法攔截類的__init__方法。我們再來看一下它怎麼使用的。

@singleins

class person:

def __init__(self, name, age):

self.name = name

self.age = age

def __str__(self):

return "{} 的年齡是{}".format(self.name, self.age)

zhangsan = person('zhangsan', 30)

lisi = person('lisi', 29)

print(zhangsan)

print(lisi)

最終的輸出結果是:

zhangsan 的年齡是30

zhangsan 的年齡是30

為什麼結果是一樣的?因為在建立例項的過程中,__init__函式被oncall函式攔截,此時會進入到createinstance函式的流程中,會對這個類例項進行判斷,如果不存在這個類的例項,那麼就初始化乙個後返回,如果存在,直接返回第乙個建立的類例項。因此最終只有乙個類例項存在,就實現類單例類。

上面最開始的位置我們說了,函式裝飾器和類裝飾器都是攔截函式呼叫,在函式裝飾器實現類呼叫攔截的地方我們看到,它是通過函式裝飾器內部的函式來實現攔截的。如果是類裝飾器呢,它通過什麼來攔截呢?

答案是call函式來攔截,我們來看一下類裝飾器的實現**:

class singleins:

def __init__(self, cls):

self.cls = cls

self.ins = none

def __call__(self, *args):

if self.ins is none:

self.ins = self.cls(*args)

return self.ins

**和函式裝飾器相比,其實功能沒有太多變化,通過__call__方法來接收被攔截類的初始化函式引數args,然後用args來初始化類例項。但是只在這個類還沒有例項的情況下進行初始化,否則直接返會初始化好的類。

我們來看一下應用的**:

@singleins

class person:

def __init__(self, name, age):

self.name = name

self.age = age

def __str__(self):

return "{} 的年齡是{}".format(self.name, self.age)

zhangsan = person('zhangsan', 30)

lisi = person('lisi', 29)

print(zhangsan)

print(lisi)

最終的結果和上面函式裝飾器的一樣,如下所示:

zhangsan 的年齡是30

zhangsan 的年齡是30

函式裝飾器 類裝飾器

一 函式裝飾函式 defwrapfun func definner a,b print function name func.name r func a,b return r return inner wrapfun defmyadd a,b return a b print myadd 2,3 二...

python裝飾器 函式裝飾器,類裝飾器

只要實現此 模式,這個obj就叫乙個裝飾器 參考 函式裝飾器 例子 def decorator func def inner args,kwargs print before.res func args,kwargs print after.return res return inner decor...

python 裝飾器 函式裝飾器 類裝飾器

python函式裝飾器和類裝飾器筆記.usr bin env python coding utf 8 author ivan file decorators.py version from functools import wraps 裝飾器 目的是為了給函式新增附加功能 1.不帶引數裝飾器 此方式...