init 和 new
- __init__其实不是实例化对象后第一个调用的方法,最先调用的方法其实是__new__方法。
- new方法作用:a.在内存中为对象分配空间 ;b.返回对象的引用
- 一个对象的实例化的过程是先执行new方法, 如果没有重写new方法,默认调用object里面的new方法,python解释器首先会调用new方法为对象分配空间,返回一个实例对象,传递给init方法,然后再调用init方法,对这个对象进行初始化
class Human(object):
def __init__(self, name):
self.name = name # 实例属性
print('这是init中的self:', self)
print('名字是:', self.name)
def __new__(cls, *args, **kwargs):
print('这是new中的cls:', cls)
print('这是new方法')
print('这是new方法中需要返回的值:', object.__new__(cls))
return object.__new__(cls) # 返回对象引用
print('这是类:', Human) # 这是类: <class '__main__.Human'>
hu = Human('LIULIU')
# 这是new中的cls: <class '__main__.Human'>
# 这是new方法
# 这是new方法中需要返回的值: <__main__.Human object at 0x0000018BB396A3D0>
# 这是init中的self: <__main__.Human object at 0x0000018BB396A3D0>
# 名字是: LIULIU
print('这是第一次实例化的对象:', hu) # 这是第一次实例化的对象: <__main__.Human object at 0x0000018BB396A3D0>
# 总结:
# 1.init方法是什么时候被自动调用? 实例化的时候调用
# 2.new方法是用来创建实例对象,new方法是从哪里来的? object
# 3.self 里面是什么? self代表实例对象本身; 他是new方法创建的,然后发送给init方法去使用
# 4.init和new的区别
# new方法:创建对象; init方法:初始化对象
# new:返回对象引用 init:定义实例属性
# new:是类级别的方法 init:是实例级别的方法
单例模式
- 单例模式是一个特殊的类,这个类只能创建一次实例
- 单例模式下可以节省内存空间,实例化不同对象会产生不同的内容地址,造成资源浪费
- 实现单例模式的方法:
- 1.通过@classmethod
- 2.通过装饰器实现
- 3.通过__new__实现 (重点)
- 4.通过导入模块时实现
# 单例设计流程
# 1. 定义一个类属性,初始值是None, 用于记录单例对象的引用
# 2.重写new方法
# 3.进行判断, 如果类属性是None, 把new方法返回的对象引用保存进去
# 4.返回类属性中记录的对象引用
# 通过new来实现单例模式
class Eaxm(object):
# 记录第一个被创建的对象引用
ins = None # 类属性
def __init__(self):
print('init方法')
def __new__(cls, *args, **kwargs):
# 1.判断类属性是否为空
if cls.ins == None:
# 2.调用父类的new方法,为第一个对象分配空间
cls.ins = object.__new__(cls)
# 3.返回类属性保持的对象引用
return cls.ins
# 单例模式:每一次实例化所创建的实例都是同一个,内存地址都一样
a1 = Eaxm()
print(a1)
a2 = Eaxm()
print(a2)
a3 = Eaxm()
print(a3)
# init方法
# <__main__.Eaxm object at 0x000001F7AE25A460>
# init方法
# <__main__.Eaxm object at 0x000001F7AE25A460>
# init方法
# <__main__.Eaxm object at 0x000001F7AE25A460>
# 通过装饰器来实现
def outer(fn): # fn是被修饰的类名 -- Test
# 创建一个字典来保存类的实例对象
ins = {}
def inner():
# 先判断这个类有没有对象
if fn not in ins:
# 创建一个对象,保存在字典中
ins[fn] = fn() # fn是类名, 在ins中是键; fn()是实例化的对象, 在ins中是值
print('inner函数中fn', fn) # <class '__main__.Test'>
print('inner函数中ins', ins) # {<class '__main__.Test'>: <__main__.Test object at 0x000001D6AFACCC48>}
print('inner函数中ins[fn]', ins[fn]) # <__main__.Test object at 0x000001D6AFACCC48>
# 将实例对象返回
return ins[fn] # <__main__.Test object at 0x000001F45DCC4670>
return inner # <__main__.Test object at 0x000001F45DCC4670>
@outer # 装饰器修饰的是Test类
class Test(object):
pass
te = Test()
print(te)
te2 = Test()
print(te2)