单例模式概念什么时候能用到单例模式单例模式的好处
目录
一、单例模式的概念 类每次实例化的时候都会创建一个新的对象,如果要求类只能被实例化一次该怎么做?
二、什么时候能用到单例模式?
三、单例模式的好处 单例模式好处 代码目录结构
一、单例模式的概念1.类每次实例化的时候都会创建一个新的对象,如果要求类只能被实例化一次该怎么做?
__new__ 方法是用来创建实例对象的,通过类去创建方法的时候,实际上类自动调用的__new__ 方法。
调用完 __new__ 方法,创建好对象之后,再把对象交给__init__ 做一个初始化的设置。
创建一个对象的时候,我们自己不需要调用,我们的这个类自动调用这2个方法。这2个方法叫做魔术方法(因为它们是双下划线开头,双下划线结尾的)。
这个 __new__ 方法:def __new__(cls.*args,**kwargs): print("-----new方法-----") return object.__new__(cls)
刚才重写之后,感觉重写这个东西还要调用父类的 __new__ 方法,然后将它的结果进行返回,好像没有什么作用。
单例模式: 就是我们创建一个类,这个类只能被实例化一次,也就是说这个类只能创建出来一个实例对象,这种叫做单例模式。二、什么时候能用到单例模式?
比如你当前写了个小系统,在系统里有些相关的配置(是整个系统通用的配置),如果把这所有的配置都放在一个类里面存储,这个时候,在程序的任何地方用到的配置都是一样的。
这个时候,用到的时候,创建一个类,给里面添加一些配置。要修改的时候,再创建一个类,然后添加一些同样的配置,这个时候就是浪费资源。 三、单例模式的好处1.单例模式好处
不管你实例化多少次,它始终只返回第一次创建的对象。不管你什么时候创建,它始终返回这一个对象。
比如在这个day_01.py里面实现了一个单例模式: # 1、多个装饰器装饰同一个函数 # 2、python中类里面三个内置的装饰器 # 3、用类实现装饰器 import time def wrapper(func): def count_time(*args,**kwargs): print("计算时间的装饰器") start_time=time.time() func(*args,**kwargs) end_time=time.time() print("函数运行的时间为:{:.5f}".format(end_time-start_time)) return count_time with open("data/user.txt") as f: users=eval(f.read()) def login_check(func): def ado(*args,**kwargs): print("登录校验的装饰器") if not users["token"]: print("-----登录页面-------") username=input("账号:") password=input("密码:") if users["user"] == username and users["pwd"] == password: users["token"] =True func(*args,**kwargs) else: func() return ado @login_check # 第二步进行装饰 count_time---->func=login_check(func) func指向的是ado这个函数 @wrapper # 第一步进行装饰 func=wrapper(func) func指向的是count_time这个函数。 def func(): time.sleep(3) print("这是是需要被装饰器的函数") # 从下往上装饰,从上往下执行 func() class MyTest(object): def __init__(self,name):#设置一个初始化属性叫做name self.name = name @classmethod # 被classmethod装饰了之后,该方法就是一个类方法 def add(cls):# cls 代表的是类本身 print("add") print(cls) @staticmethod # 静态方法 实例和类都可以调用 def static(): print("这个是静态方法") @property # 设定只读属性 def read_attr(self): print("这个装饰器装饰完了之后,该方法可以像属性一样被调用") return "20岁" def sub(self):# self 代表的是实例本身 print("sub中的self",self) # MyTest.static() #类调用 # # t= MyTest("Tester") # 通过name可以访问到这个属性,可以对这个属性进行更改 # t.name="lily" # print(t.name) # t.read_attr="19岁" # print(t.read_attr) # t.static()#实例调用 # t.add() # t.sub()
给它创建了一个对象,给它添加好了一些配置。
在day_02.py里没有用到: class MyClass(object): def __init__(self,name): self.name=name print("__init__方法调用了") # 重写下__new__方法 def __new__(cls, *args, **kwargs): print("这个是new方法") # 子类里调用下父类的方法,并进行返回 return object.__new__(cls) m = MyClass("Tester") # print(m.name) # print(m)
在这里要把实例对象倒过来。
忘记创建的实例对象叫做什么名字了,记住它的类名就行了。找到定义单例模式的那个类,把那个类倒进来。
这里再创建一个对象,那么这个对象还是原来那边创建好的对象。原来设置好的属性,这里也全部都有,不需要再全部添加。
在这里通过 Mytest 创建出来一个对象。
把day_01.py中代码修改成这样: # 1、多个装饰器装饰同一个函数 # 2、python中类里面三个内置的装饰器 # 3、用类实现装饰器 import time def wrapper(func): def count_time(*args,**kwargs): print("计算时间的装饰器") start_time=time.time() func(*args,**kwargs) end_time=time.time() print("函数运行的时间为:{:.5f}".format(end_time-start_time)) return count_time with open("../class_03day/data/user.txt") as f: users=eval(f.read()) def login_check(func): def ado(*args,**kwargs): print("登录校验的装饰器") if not users["token"]: print("-----登录页面-------") username=input("账号:") password=input("密码:") if users["user"] == username and users["pwd"] == password: users["token"] =True func(*args,**kwargs) else: func() return ado @login_check # 第二步进行装饰 count_time---->func=login_check(func) func指向的是ado这个函数 @wrapper # 第一步进行装饰 func=wrapper(func) func指向的是count_time这个函数。 def func(): time.sleep(3) print("这是是需要被装饰器的函数") # 从下往上装饰,从上往下执行 func() class MyTest(object): def __init__(self):#设置一个初始化属性叫做name pass @classmethod # 被classmethod装饰了之后,该方法就是一个类方法 def add(cls):# cls 代表的是类本身 print("add") print(cls) @staticmethod # 静态方法 实例和类都可以调用 def static(): print("这个是静态方法") @property # 设定只读属性 def read_attr(self): print("这个装饰器装饰完了之后,该方法可以像属性一样被调用") return "20岁" def sub(self):# self 代表的是实例本身 print("sub中的self",self) MyTest.static() #类调用 # t= MyTest("Tester") t= MyTest() # 通过name可以访问到这个属性,可以对这个属性进行更改 t.name="lily" # print(t.name) # t.read_attr="19岁" print(t.read_attr) # t.static()#实例调用 # t.add() # t.sub()
去掉一个name属性。
文件qh_05day_02.py from qh_05day.qh_05day_01 import MyTest t1=MyTest() class MyClass(object): def __init__(self,name): self.name=name print("__init__方法调用了") # 重写下__new__方法 def __new__(cls, *args, **kwargs): print("这个是new方法") # 子类里调用下父类的方法,并进行返回 return object.__new__(cls) m = MyClass("Tester") # print(m.name) # print(m)
t1对象会拥有t对象拥有的属性。
t对象,在这里你给它设置了什么属性。在t1对象那里都有,不需要重新设置了。
通过MyTest这个类去创建的时候,始终只会返回一个实例。不管你用这个类去创建实例多少次,最终给你返回的始终只有一个对象。就是它第一次创建的那个对象。
这个类只能实例化一次,只能创建一个实例化对象。 不管你创建多少次,只能一个。2.代码目录结构
打开文件,我的本地路径是:C:Users18210Desktop所有文件pythonpython_ck01qh_05day