python单例模式魔法方法
1.__init__()和__new__()
1.1__init__():初始化对象
上篇文章提到过
1.2__new__():object基类提供的内置静态方法
作用:1.在内存中为对象分配空间 2.返回对象的引用
注意:重写__new__()一定要return super().__new__(cls),否则python解释器得不到分配空间的对象引用,就不会调用__init__()
class Test(object):
def __init__(self):
print("这是__init__()")
def __new__(cls, *args, **kwargs): #默认参数,不能去除 cls代表类本身
print("这是__new__")
#对父类进行扩展 super().方法名() #否则不执行__init__()函数(覆盖了父类的__new__()方法)
return super().__new__(cls) #父类中的__new__()是静态方法,形参里面有cls,实参必须传cls
te = Test()
执行步骤:一个对象的实例化过程:首先执行__new__(),如果没有写__new__(),默认调用object里面的__new__(),返回一个实例对象,然后再去调用__init__(),对对象进行初始化。
class Person(object):
def __new__(cls, *args, **kwargs):
print("这是__new__")
print("返回值:",super().__new__(cls))
return super().__new__(cls)
def __init__(self,name):
self.name = name
print("名字是:",self.name)
p1 = Person('panda')
print("创建的对象p1",p1)
p2 = Person('monkey')
print("创建的对象p2", p2)
重写__new__()方式时的返回值就是创建的对象,是为了在内存中为对象分配空间,返回对象的引用。
总结:__init__()和__new__()
1.__new__()是创建对象,__init__()是初始化对象
2.__new__()是返回对象的引用,__init__()定义实例属性
3.__new__()是类级别的方法,__init__()是实例级别的方法
2.单例模式
2.1含义:
是一种常用的软件设计模式,该模式的主要目地是确保某一个类只有一个实例存在。当你希望整个系统中,某个类只出现一个实例是,单例模式就能派上用场(每一次实例化创建的对象都是同一个,内存地址都一样)
优点:可以节省内存空间,减少了不必要的资源浪费
弊端:多线程访问的时候容易引发线程安全问题
2.2方式:
1.通过@classmethod
2.通过装饰器实现
3.通过重写__new__()实现(重点)
4.通过导入模块实现
这里主要介绍后两种
2.3通过重写__new__()方法实现单例模式
设计流程
1.定义一个类属性,初始值为None,用来记录单例对象的引用
2.重写__new__()方法
3.进行判断,如果类属性是None,把__new__()返回的对象引用保存进去
4.返回类属性中记录的对象的引用
class Singleton(object):
obj = None
def __new__(cls, *args, **kwargs):
print("这是__new__方法")
if cls.obj == None:
cls.obj = super().__new__(cls)
return cls.obj
def __init__(self):
print("这是一个__init__()方法")
s1 = Singleton()
print(s1)
s2 = Singleton()
print(s2)
2.4通过导入模块实现单例模式
模块就是天然的单例模式
from test1 import te as t1
from test1 import te as t2
print(t1,id(t1))
print(t2,id(t2))
2.5应用场景
1.回收站对象
2.音乐播放器,一个音乐播放软件负责音乐播放的对象只有一个
3.开发游戏软件 场景管理器
4.数据库配置 数据库连接池的设计
3.魔法方法&魔法属性
含义:python中,__xx__()的函数叫做魔法方法,指的是具有特殊功能的函数
3.1__doc__:类/函数信息的描述
class Person(object):
"""人类---类信息的描述"""
pass
print(Person.__doc__)
3.2__module__:表示当前对象所在的模块
3.3__class__:表示当前操作对象所在的类
3.4__str__():对象的描述信息
如果在类中定义了该方法,那么在打印对象时,默认输出该方法的返回值,也就是打印方法中的return数据
注意:__str__()必须返回一个字符串
class C:
def __str__(self):
return "这里是str的返回值"
c = C()
print(c)
3.5__del__():析构函数,在程序结束时会调用,或者在删除某个对象时也会被调用
上篇文章也提到过
3.6__call__():使一个实例化对象成为可调用对象,就像函数那样可以调用(调用一个可调用的实例对象,就是调用它的__call__()方法)
可调用对象:函数,内置函数和类都是可调用对象,凡是可以把一对()应用到某个对象身上都称为可调用对象
callable():判断一个对象是否是可调用对象
class A:
def __call__(self, *args, **kwargs):
print("这是一个call方法")
a = A()
a() #这是一个call方法
print(callable(a)) # True