单例模式
整个过程中只有一个实例,所有生成的实例都指向同一块内存空间
实现单例的第一种方法(通过类的绑定方法)
#当用户输入端口和地址,实例化产生新对象
#当用户不输入端口和地址,每次拿到的对象,都是同一个
class Sql():
instance=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)