一,私有属性判断法
class Single:
_obj = None
_init_flag = True
def __new__(cls, *args, **kwargs):
if cls._obj == None:
cls._obj = super().__new__(cls)
return cls._obj
def __init__(self,name):
if Single._init_flag:
self.name = name
print('11111')
Single._init_flag = False
二,类方法
# 类方法,调用绑定给类的方法产生对象
class Single2:
_obj = None
def __init__(self,name,age):
print('222222222')
self.name = name
self.age = age
@classmethod
def singleton(cls,*args,**kwargs):
if not cls._obj :
cls._obj = cls(*args,**kwargs)
return cls._obj
三,装饰器法
# 装饰器方法
def single_wrapper(cls):
_instance = {}
def inner(*args, **kwargs):
if cls not in _instance:
_instance[cls] = cls(*args, *kwargs)
return _instance[cls]
return inner
@single_wrapper
class Single3:
def __init__(self, name, age):
print('3333333333')
self.name = name
self.age = age
四,元类法
# 元类方法,传入相同参数返回同一个对象,不同参数返回不同对象
class MyMeta(type):
# 1、先触发元类里面的__init__
def __init__(self, name, base, attrs): # self --> Goo
# *** 造空的对象, 然后赋值给了Goo类中的_instance类属性
self._instance = object.__new__(self)
self._argument = []
self._obj = {}
# 将类名、基类、类的名称空间,传给type里面的__init__
super().__init__(name, base, attrs)
# type.__init__(self, name, base, attrs)
# 2、当调用Goo类时,等同于调用了由元类实例化的到的对象
def __call__(self, *args, **kwargs):
# 判断调用Goo时是否传参
if args or kwargs:
list = [args,kwargs]
if list in self._argument:
position = self._argument.index([args, kwargs])
obj = self._obj[position]
return obj
else:
obj = object.__new__(self)
self.__init__(obj, *args, **kwargs)
self._argument.append([args,kwargs])
position = self._argument.index([args,kwargs])
self._obj[position]=obj
return obj
else:
return object.__new__(self)
class Goo(metaclass=MyMeta): # Goo = MyMeta(Goo)
def __init__(self, ip,port):
self.ip=ip
self.pot=port
五,导入模块法
# 导入模块法
test.py
class Single4:
pass
instance = Single4()
from scripts.test import instance
g = instance
h = instance
print(g == h)