ps:类只要加括号就会生成一个新的对象,无论参数是否相同,单例模式排除在外.
class Demo:
pass
obj1 =
Demo()
obj2 =
Demo()
print(id(obj1))
# 1594519955888
print(id(obj2))
# 1594519955832
单例:
多次调用类拿到的是同一个对象
单例的实现:
<1>基于classmethod
class Mysql(object):
_instance =
None
def __init__(self, host, port):
self.host =
host
self.port =
port
@classmethod
def singelton(cls):
if not cls._instance:
cls._instance = cls(
'127.0.0.1',8080
)
obj1 =
Mysql.singelton()
obj2 =
Mysql.singelton()
obj3 = Mysql(
'168.192.1.1',8088
)
print(id(obj1), id(obj2), id(obj3))
# 1731962064 1731962064 1736639656680
<2>基于装饰器
# 基于装饰器 本质:会将紧挨着它的变量名当做参数传入
def singelton(cls):
_instance = cls(
'127.0.0.1',8080
)
def inner(*args, **
kwargs):
if args
or kwargs:
obj = cls(*args, **kwargs)
# cls 是真正的 Mysql 类
return obj
return _instance
return inner
@singelton # Mysql = singelton(Mysql) 函数加括号优先级最高,此时 Mysql就是inner
class Mysql(object):
def __init__(self, host, port):
self.host =
host
self.port =
port
obj1 = Mysql()
# 其实是 inner()
obj2 =
Mysql()
obj3 = Mysql(
'168.192.1.1',8088
)
print(id(obj1), id(obj2), id(obj3))
# 2661019235384 2661019235384 2661019235328
<3>基于元类
class MyClass(type):
def __call__(self, *args, **
kwargs):
# 调用 Mysql 中的 _instance
if not getattr(self,
'_instance'):
# 此时的self是Mysql
self._instance = super().
__call__(*args, **kwargs)
# 调用父类的__call__产生对象赋值给 _instance 这个对象就是Mysql的对象
# __call__固定会做三件事:
# 1.产生空对象 __new__
# 2.初始化对象 __init__
# 3.返回该对象 return obj
return self._instance
pass
class Mysql(object, metaclass=MyClass):
# 类加括号会走它元类中的__call__方法
_instance =
None
def __init__(self, host, port):
self.host =
host
self.port =
port
obj1 = Mysql(
'168.192.1.1',8088
)
obj2 = Mysql(
'168.192.1.1',9999
)
print(id(obj1), id(obj2))
# 2107832088112 2107832088112
<4>基于__new__
class Mysql(object):
_instance =
None
def __init__(self, host, port):
self.host =
host
self.port =
port
# __new__拦截类的创建过程,在类创建前先走__new__, 这里的__new__在Mysql实例化时触发
def __new__(cls, *args, **
kwargs):
if not cls._instance:
cls._instance = object.
__new__(cls)
# 这里的cls每次都是最后实例化时那个Mysql
return cls._instance
obj1 = Mysql(
'168.192.1.1',8088
)
obj2 = Mysql(
'168.192.1.1',9999
)
print(id(obj1), id(obj2))
# 1512390747976 1512390747976
<5>基于模块
class Settings(object):
pass
settings = Settings()
单例设计模式1.py
from 单例设计模式1
import settings
def func():
print(id(settings))
单例设计模式2.py
# 1.
from 单例设计模式1
import settings
print(id(settings))
# 3078907535488
from 单例设计模式1
import settings
print(id(settings))
# 3078907535488
# 模块导入一次后就不会在导入
# 2.
from 单例设计模式1
import settings
from 单例设计模式2
import func
print(id(settings))
# 2381785037456
func()
# 2381785037456
# 3.
from 单例设计模式1
import settings,Settings
print(id(settings))
# 2080793135592
print(id(Settings()))
# 2080793135424