python单例模式继承_python单例模式

本文介绍了如何使用Python的装饰器实现基本的单例模式,并进一步扩展为可继承的单例模式,使得单例类及其子类共享同一个实例。通过修改init方法并使用装饰器,确保了在创建实例时的正确性和一致性。
摘要由CSDN通过智能技术生成

单例模式是常见的一种设计模式,它是针对类的一种描述,因此,我们可以使用python的decorator来实现通用的单例模式。

一.基本的单例模式

首先建立我们的decorator。我们需要为classType建立_instance和_lock成员:

Python

def singleton(classType):

classType._instance = None

classType._lock = Lock()

return classType

1

2

3

4

defsingleton(classType):

classType._instance=None

classType._lock=Lock()

returnclassType

然后为class建立getInstance函数:

Python

def __getInstance(classname):

if classname._instance is None:

classname._lock.acquire()

if classname._instance is None:

classname._instance = classname()

classname._lock.release()

return classname._instance

1

2

3

4

5

6

7

def__getInstance(classname):

ifclassname._instanceisNone:

classname._lock.acquire()

ifclassname._instanceisNone:

classname._instance=classname()

classname._lock.release()

returnclassname._instance

然后在我们的decorator中,将getInstance函数添加到class上:

Python

classType.getInstance = classmethod(__getInstance)

1

classType.getInstance=classmethod(__getInstance)

现在我们的代码长这样。这个decorator已经具备了基本功能:

Python

def __getInstance(classType):

if classType._instance is None:

classType._lock.acquire()

if classType._instance is None:

classType._instance = classType()

classType._lock.release()

return classType._instance

def singleton(classType):

classType._instance = None

classType._lock = Lock()

classType.getInstance = classmethod(__getInstance)

return classType

1

2

3

4

5

6

7

8

9

10

11

12

13

def__getInstance(classType):

ifclassType._instanceisNone:

classType._lock.acquire()

ifclassType._instanceisNone:

classType._instance=classType()

classType._lock.release()

returnclassType._instance

defsingleton(classType):

classType._instance=None

classType._lock=Lock()

classType.getInstance=classmethod(__getInstance)

returnclassType

使用方法如下:

Python

@singleton

class XXX(object):

# add class definitions

pass

1

2

3

4

@singleton

classXXX(object):

# add class definitions

pass

二.可继承的单例模式

现在让我们为这个单例模式添加一些功能:我们让被这个单例类可以产生子类,且子类也是单例类,和父类共享同一个instance。为此,我们必须修改被修饰的单例类的init方法,在其中设置instance为自身:

Python

def __singleton_init(self):

# check whether instance has existed

if self._instance is not None:

raise SingletonExistedError(type(self))

# set instance of this class and its ancestor classes to self

for baseClass in inspect.getmro(type(self)):

if '_instance' in baseClass.__dict__:

baseClass._instance = self

1

2

3

4

5

6

7

8

9

def__singleton_init(self):

# check whether instance has existed

ifself._instanceisnotNone:

raiseSingletonExistedError(type(self))

# set instance of this class and its ancestor classes to self

forbaseClassininspect.getmro(type(self)):

if'_instance'inbaseClass.__dict__:

baseClass._instance=self

SingletonExistedError为自定义的error类型:

Python

class SingletonExistedError(Exception):

def __init__(self, classType):

super(SingletonExistedError, self).__init__('trying to construct instance of singleton class ' + classType.__name__ + ' while an instance has already existed!')

1

2

3

classSingletonExistedError(Exception):

def__init__(self,classType):

super(SingletonExistedError,self).__init__('trying to construct instance of singleton class '+classType.__name__+' while an instance has already existed!')

现在我们需要把这个新的init函数添加到被修饰的单例类的init函数上。很自然的,我们又可以利用函数的decorator来办成这件事情,就像这样:

Python

def __singleton_init_decorator(init_func):

def __singleton_init(self):

# check whether instance has existed

if self._instance is not None:

raise SingletonExistedError(type(self))

# set instance of the class and ancestor singletons to self

for baseClass in inspect.getmro(type(self)):

if '_instance' in baseClass.__dict__:

baseClass._instance = self

init_func(self)

return __singleton_init

1

2

3

4

5

6

7

8

9

10

11

12

13

def__singleton_init_decorator(init_func):

def__singleton_init(self):

# check whether instance has existed

ifself._instanceisnotNone:

raiseSingletonExistedError(type(self))

# set instance of the class and ancestor singletons to self

forbaseClassininspect.getmro(type(self)):

if'_instance'inbaseClass.__dict__:

baseClass._instance=self

init_func(self)

return__singleton_init

最后,在我们的singleton decorator上加上这句代码:

Python

classType.__init__ = __singleton_init_decorator(classType.__init__)

1

classType.__init__=__singleton_init_decorator(classType.__init__)

大功告成!附上完整代码:

Python

class SingletonExistedError(Exception):

def __init__(self, classType):

super(SingletonExistedError, self).__init__('trying to construct instance of singleton class ' + classType.__name__ + ' while an instance has already existed!')

def __getInstance(classType):

if classType._instance is None:

classType._lock.acquire()

if classType._instance is None:

classType._instance = classType()

classType._lock.release()

return classType._instance

def __singleton_init_decorator(init_func):

def __singleton_init(self):

# check whether instance has existed

if self._instance is not None:

raise SingletonExistedError(type(self))

# set instance of the class and ancestor singletons to self

for baseClass in inspect.getmro(type(self)):

if '_instance' in baseClass.__dict__:

baseClass._instance = self

init_func(self)

return __singleton_init

def singleton(classType):

classType._instance = None

classType._lock = Lock()

classType.getInstance = classmethod(__getInstance)

classType.__init__ = __singleton_init_decorator(classType.__init__)

return classType

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

33

classSingletonExistedError(Exception):

def__init__(self,classType):

super(SingletonExistedError,self).__init__('trying to construct instance of singleton class '+classType.__name__+' while an instance has already existed!')

def__getInstance(classType):

ifclassType._instanceisNone:

classType._lock.acquire()

ifclassType._instanceisNone:

classType._instance=classType()

classType._lock.release()

returnclassType._instance

def__singleton_init_decorator(init_func):

def__singleton_init(self):

# check whether instance has existed

ifself._instanceisnotNone:

raiseSingletonExistedError(type(self))

# set instance of the class and ancestor singletons to self

forbaseClassininspect.getmro(type(self)):

if'_instance'inbaseClass.__dict__:

baseClass._instance=self

init_func(self)

return__singleton_init

defsingleton(classType):

classType._instance=None

classType._lock=Lock()

classType.getInstance=classmethod(__getInstance)

classType.__init__=__singleton_init_decorator(classType.__init__)

returnclassType

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值