有这么一种场景,Web服务中有一个全局资源池,在需要使用的地方就自然而言引用该全局资源池即可,此时可以将该资源池以单例模式实现。随后,需要为某一特殊业务场景专门准备一个全局资源池,于是额外复制一份代码新建了一个全局资源池,这里的问题是本身两个池子没有任何区别,仅仅为了隔离资源而需要两个单例,这里存在一个代码复用问题。
Python 使用单例模式最佳方案是使用元类
class Singleton(type):
"""
单例模式的元类
"""
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
为解决上述问题,Python 中推荐以如下方式实现:
class Singleton(type):
"""
单例模式的元类
"""
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class SingletonBean(metaclass=Singleton):
"""
单例Bean父类
"""
pass
class ConnectionPool:
"""
公共代码
"""
def __init__(self, min_size, max_size, params):
print(min_size, max_size, params)
class ConnectionPool4A(SingletonBean, ConnectionPool):
def __init__(self):
super().__init__(
min_size=10,
max_size=100,
params={
...: ...
}
)
class ConnectionPool4B(SingletonBean, ConnectionPool):
def __init__(self):
super().__init__(
min_size=30,
max_size=30,
params={
...: ...
}
)
o1 = ConnectionPool4A()
print(id(o1))
o2 = ConnectionPool4B()
print(id(o2))
o3 = ConnectionPool4A()
print(id(o3))
o4 = ConnectionPool4B()
print(id(o4))
但是由于元类冲突,可能不一定可以:
class MyMeta1(type):
...
class MyMeta2(type):
...
class A1(metaclass=MyMeta1):
...
class A2(metaclass=MyMeta2):
...
class B(A2, A1):
...
print(type(B))