单例模式
整个过程中只有一个实例,所有生成的实例都指向同一块内存空间
实现单例的第一种方法(通过类的绑定方法)
#当用户输入端口和地址,实例化产生新对象 #当用户不输入端口和地址,每次拿到的对象,都是同一个 class Sql(): isinstance=None def __init__(self,port,host): self.port=port self.host=host @classmethod def get_num(cls): import setting if not cls.instance: cls.instance=cls(setting.PORT,setting.HOST) return cls.instance #m每次调用get_num 拿到的对象都是同一个 s1=Sql.get_num() s2=Sql.get_num() print(s1) print(s2) s3=Sql('33066','8.8.8.8') print(s3) <__main__.Sql object at 0x0000027E22BE6C18> <__main__.Sql object at 0x0000027E22BE6C18> <__main__.Sql object at 0x0000027E22BE6BE0>
#setting文件 PORT=3306 HOST='127.0.0.1'
第二种方法:通过装饰器
#当用户输入端口和地址,实例化产生新对象 #当用户不输入端口和地址,每次拿到的对象,都是同一个
def get_num(cls): #cls就是Sql这个类 import setting instance=cls(setting.PORT,setting.HOST) def wrapper(*args,**kwargs): if len(args)!=0 or len(kwargs)!=0: #表示传了参数,生成新对象 res=cls(*args,**kwargs) return res else: return instance return wrapper @get_num #会把下面的Sql当中参数传入,相当于:Sql=get_num(Sql) class Sql(): def __init__(self,port,host): self.port=port self.host=host s1=Sql() s2=Sql() s3=Sql('33360','8:8:8:8') print(s1) print(s2) print(s3)
第三种:通过元类
#当用户输入端口和地址,实例化产生新对象 #当用户不输入端口和地址,每次拿到的对象,都是同一个 class Mymeta(type): def __init__(self,name,bases,dic): import setting self.instance=self(setting.PORT,setting.HOST) def __call__(self, *args, **kwargs): if len(args)!=0 or len(kwargs)!=0: obj=object.__new__(self) obj.__init__(*args,**kwargs) return obj else: return self.instance class Sql(metaclass=Mymeta): def __init__(self,port,host): self.port=port self.host=host s1=Sql() s2=Sql() s3=Sql('33306','8:8:8:8') print(s1) print(s2) print(s3)
第四种:通过模块导入(python的模块是天然的单例)
#num import setting class Sql(): def __init__(self,port,host): self.port=port self.host=host s1=Sql(setting.PORT,setting.HOST)
def test(): from num import s1 print(s1) def test2(): from num import s1 as s2 print(s2) test() test2() from num import s1 from num import Sql s2=Sql('3306','8:8:8:8') print(s1) print(s2)