python 实现单例模式

单例模式

作用

只生成一个实例对象,减少了对系统资源的开销,当一个对象的产生需要比较多的资源,如读取配置文件,产生其他依赖对象时,可以产生一个单例对象,然后永久驻留在内存中,从而极大的降低开销

应用
  1. 使用框架时只加载一次配置文件
  2. scrapy框架中管道文件与数据库建立连接和断开连接只执行一次
  3. python的模块就是天生的单例模式。导入一次之后就不会再次导入
实现单例的几种方式
  1. 使用模块
    python的模块就是天然的单例模式,模块在第一次导入时会生成.pyc文件,当第二次导入时,就会直接加载.pyc文件,而不会再次执行模块代码
  2. 使用装饰器
def Singleton(cls):
	_instance = {}
	def _singleton(*args,**kwargs):
		if cls not in _instance:
			_instance[cls] = cls(*args,**kwargs)
		return _instance[cls]
	return _singleton

@Singleton
class A:
	pass
a1 = A()
a2 = B()
print(a1)
print(a2)	#打印出来的对象a1,a2地址是一样的,实现了单例
  1. 使用__new__(cls)
    推荐使用,方便
#模型示例
class Mysingleton:
	#通过__obj类属性保存该类创建的单例
	__obj = None
	#加一个标记
	__init_flag = True
	
	#重写魔法函数__new__(cls)
	#魔法函数_new__(cls)用于创建类实例,在你实例化类时,在__init__()之前调用
	def __new__(cls,*args,**kwargs):
		#如果类属性为空,则调用object类的__new__()创建类实例
		if cls.__obj == None:
			cls.__obj = super().__new__(cls)
		
		return cls.__obj
		
	#__init__()在你创建了类实例之后调用
	def __init__(self,name):
		#如果类属性__init_flag为True,则执行一次,之后就不执行了
		if Mysingleton.__init_flag:
			print("init....")
			self.name = name
			MySingleTon.__init_flag = False

a = MySingleton("aa")	#会打印出init....
b = MySingleton("bb")	#不再打印出init...
print(a)
print(b)
#打印出来的a和b的地址是一样的,说明打印出来的是一个对象
#示例2
class CarFactory:
	#类属性
	#存放单例
	__obj = None
	__init_flag = True

	def create_car(self,brand):
		if brand == "奔驰":
			return Benz()
		else brand == "宝马":
			return BMW()
		elif brand == "比亚迪":
			return BYD()
		else:
			return "未知名品牌,无法创建"
		
	def __new__(cls,*args,**kwargs):
		if cls.__obj == None:
			cls.__obj = object.__new__(cls)
		return cls.__obj

	def __init__(self):
		if CarFactory.__init._flag:
			print("init CarFactory....")
			CarFactory.__init_flag = False
			
class Benz:
	pass
class BMW:
	pass
class BYD:
	pass

factory = CarFactory()
c1 = factory.create_car("奔驰")
print(c1)	#init CarFactory...只打印一次
c2 = factory.create_car("比亚迪")
print(c2)

factory2 = CarFactor()
print(factory)
print(factory2)	#factory2和factory对象地址一样,说明是同一个实例(单例)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值