用
__new__
实现
# 实例化一个jatrix
class Singleton(object):
__instance = None
__first_init = None
def __new__(cls, age, name):
if not cls.__instance:
Singleton.__instance = object.__new__(cls)
return cls.__instance
def __init__(self, age, name):
if not self.__first_init:
self.age = age
self.name = name
Singleton.__first_init = True
a = Singleton(21, "jatrix")
b = Singleton(2, "jatrix")
print(id(a))
print(id(b))
print(a.age)
print(b.age)
a.age = 33
print(b.age)
# 输出
# 16500112
# 16500112
# 21
# 21
# 33
为了让子类不继承父类的__new
方法,子类也应该调用object的__new__
方法
用装饰器实现单例模式
装饰器的实质就是对传进来的参数进行补充,使用装饰器可以装饰多个类
def singleton(cls, *args, **kwargs):
instance = {}
def __singleton():
if cls not in instance:
instance[cls] = cls
return instance[cls]
return __singleton
@singleton
class MyClass:
kind = "type"
def __init__(self, name):
self.name = name
@singleton
class MyAnotherClass:
name = "another"
def __init__(self, age):
self.age = age
one = MyClass()
two = MyClass()
print(id(one))
print(id(two))
another_one = MyAnotherClass()
another_two = MyAnotherClass()
print(id(another_one))
print(id(another_two))
使用元类实现
class Singleton(type):
def __init__(cls, name, bases, attrs):
super(Singleton, cls).__init__(name, bases, attrs)
cls._instance = None
def __call__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instance
class MyClass(metaclass=Singleton):
pass
one = MyClass()
two = MyClass()
print(id(one))
print(id(two))
one.name = 1
print(two.name)
使用共享属性
共享属性表示每个实例有相同的属性,但是实例不相同
class Singelton(object):
_state = {}
def __new__(cls, *args, **kwargs):
ob = super(Singelton, cls).__new__(cls)
# 类维护所有实例的共享属性
ob.__dict__ = cls._state
return ob
class MyClass(Singelton):
a = 1
one = MyClass()
two = MyClass()
print(two.a)
print(id(one))
print(id(two))
# 两个id不同 但是两者的__dict__的属性相同
print(id(one.__dict__))
print(id(two.__dict__))
网友评论