单例模式《单例模式概念、什么时候能用到单例模式、单例模式的好处》

坚持原创输出,点击蓝字关注我吧

作者:清菡
博客:oschina、云+社区、知乎等各大平台都有。

目录

  • 一、单例模式的概念

    • 1.类每次实例化的时候都会创建一个新的对象,如果要求类只能被实例化一次该怎么做呢?

  • 二、什么时候能用到单例模式?

  • 三、单例模式的好处

    • 1.单例模式好处

    • 2.代码目录结构

一、单例模式的概念

1.类每次实例化的时候都会创建一个新的对象,如果要求类只能被实例化一次该怎么做呢?

__new__方法是用来创建实例对象的,通过类去创建方法的时候,实际上类自动调用的__new__方法。

调用完__new__方法,创建好对象之后,再把对象交给__init__做一个初始化的设置。

创建一个对象的时候,我们自己不需要调用,我们的这个类自动调用这2个方法。这2个方法叫做魔术方法(因为它们是双下划线开头,双下划线结尾的)。

这个__new__方法:

def __new__(cls.*args,**kwargs):
    print('-----new方法-----')
    return object.__new__(cls)

刚才重写之后,感觉重写这个东西还要调用父类的__new__方法,然后将它的结果进行返回,好像没有什么作用。

图片来自网络

单例模式: 就是我们创建一个类,这个类只能被实例化一次,也就是说这个类只能创建出来一个实例对象,这种叫做单例模式。

二、什么时候能用到单例模式?

比如你当前写了个小系统,在系统里有些相关的配置(是整个系统通用的配置),如果把这所有的配置都放在一个类里面存储,这个时候,在程序的任何地方用到的配置都是一样的。

这个时候,用到的时候,创建一个类,给里面添加一些配置。要修改的时候,再创建一个类,然后添加一些同样的配置,这个时候就是浪费资源。

三、单例模式的好处

1.单例模式好处

不管你实例化多少次,它始终只返回第一次创建的对象。不管你什么时候创建,它始终返回这一个对象。

比如在这个qh_05day_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("zy/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("qinghan")
# 通过name可以访问到这个属性,可以对这个属性进行更改
# t.name="lily"
# print(t.name)
# t.read_attr="19岁"
# print(t.read_attr)
# t.static()#实例调用
# t.add()
# t.sub()

给它创建了一个对象,给它添加好了一些配置。

在qh_05day_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("qinghan")
# print(m.name)
# print(m)

在这里要把实例对象倒过来。

忘记创建的实例对象叫做什么名字了,记住它的类名就行了。找到定义单例模式的那个类,把那个类倒进来。

这里再创建一个对象,那么这个对象还是原来那边创建好的对象。原来设置好的属性,这里也全部都有,不需要再全部添加。

在这里通过Mytest创建出来一个对象。

把qh_05day_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/zy/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("qinghan")
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("qinghan")
# print(m.name)
# print(m)

t1对象会拥有t对象拥有的属性。

t对象,在这里你给它设置了什么属性。在t1对象那里都有,不需要重新设置了。

通过MyTest这个类去创建的时候,始终只会返回一个实例。不管你用这个类去创建实例多少次,最终给你返回的始终只有一个对象。就是它第一次创建的那个对象。

这个类只能实例化一次,只能创建一个实例化对象。 不管你创建多少次,只能一个。

2.代码目录结构

打开文件,我的本地路径是:C:\Users\18210\Desktop\所有文件\python\python_ck01\qh_05day


清菡软件测试,腾讯云年度最佳作者,非著名软件测试工程师。

文章中的图片,除标明 图片来自网络 的图片,其它图片皆为清菡本人所画。计算机知识都一样,文章是清菡的笔记。如有雷同,纯属巧合。

公众号 清菡软件测试 首发,更多原创文章:清菡软件测试 134+原创文章,欢迎关注、交流,禁止第三方擅自转载。如有转载,请标明出处。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清菡软件测试

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值