加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python设计模式之单例模式

发布时间:2020-12-17 00:17:30 所属栏目:Python 来源:网络整理
导读:div class="markdown-here-wrapper" data-md-url="https://i.cnblogs.com/EditPosts.aspx?postid=10022283"gt; h1 id="-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 24px; border-bottom: 2px solid #aaaaa

<div class="markdown-here-wrapper" data-md-url="https://i.cnblogs.com/EditPosts.aspx?postid=10022283"&gt;
<h1 id="-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 24px; border-bottom: 2px solid #aaaaaa;">一.理解单例模式
<blockquote style="margin: 1.2em 0px; border-left: 4px solid #dddddd; padding: 0px 1em; color: #777777; quotes: none;">
<p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">单例模式是一种创建型设计模式,它确保一个类有且只有一个特定类型的对象,并提供全局访问点。其意图为:


<ul style="margin: 1.2em 0px; padding-left: 2em; list-style-type: square; font-size: 16px;">
<li style="margin: 0.5em 0px; font-size: 16px;">
<p style="margin: 0.5em 0px !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">确保类有且只有一个对象被创建

  • 方法实现的单例模式

     :
         :
              hasattr(cls,):
                cls.instance=super(Singleton,cls).__new__(cls)
             cls.instance
    

    a=Singleton()
    b=Singleton()
    print(a)<span class="hljs-comment" style="color: #7285b7;">#<main.Singleton object at 0x00000220866EF400>
    print(b)<span class="hljs-comment" style="color: #7285b7;">#<main.Singleton object at 0x00000220866EF400>


    <p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">new方法为python实例化创建对象自动执行的函数,通过重写这个函数,使之先判断该类中是否有instance属性(利用反射),若没有则为创建一个对象并为该属性赋值,最后返回instance中的对象。通过这种方式我们实现了每次创建实例返回的都是类中的instance的值。


    <h3 id="2-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 20px; border-bottom: 1px solid #aaaaaa;">2.懒汉式实例化

     :
        __instance=
         :
            
        
         :
              cls.__instance:
                cls.__instance = Singleton()
             cls.__instance
    

    a=Singleton.getInstance()<span class="hljs-comment" style="color: #7285b7;">#<main.Singleton object at 0x000001C85C114B38>
    b=Singleton.getInstance()<span class="hljs-comment" style="color: #7285b7;">#<main.Singleton object at 0x000001C85C114B38>
    print(a)
    print(b)


    <p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">我觉得这种方式最好理解,感觉像是手动完成单例创建逻辑,但注意获得实例一定要调用Singleton.getInstance()方法,直接a=Singleton()相当于没用单例。


    <h3 id="3-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 20px; border-bottom: 1px solid #aaaaaa;">3.基于元类的单例实现

     :
        __instance={}
         :
             self   MetaSingleton.__instance:
                MetaSingleton.__instance[self] = super(MetaSingleton,self).__call__()
             MetaSingleton.__instance[self]
    

    <span class="hljs-class"><span class="hljs-keyword" style="color: #ebbbff;">class <span class="hljs-title" style="color: #7285b7;">Singleton<span class="hljs-params" style="color: #ffc58f;">(metaclass=MetaSingleton):
    <span class="hljs-function" style="color: #bbdaff;"><span class="hljs-keyword" style="color: #ebbbff;">def <span class="hljs-title" style="color: #7285b7;">init<span class="hljs-params" style="color: #ffc58f;">(self):
    <span class="hljs-keyword" style="color: #ebbbff;">pass

    a=Singleton()<span class="hljs-comment" style="color: #7285b7;">#<main.Singleton object at 0x0000025103984CC0>
    b=Singleton()<span class="hljs-comment" style="color: #7285b7;">#<main.Singleton object at 0x0000025103984CC0>
    print(a)
    print(b)


    <p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">执行Singleton()之后,首先会调用MetaSingleton中的call函数,如果Singleton类没有在instance中,则为其创建一个实例,也就是正常调用type中的call函数,将返回的对象存在instance中,以该类名为键,对象为值,最后返回这个对象,若instance中有该类,那就直接返回存储的对象。


    <p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">这种方式我觉得较好,不用为每个类单独创建单例模式,只需将元类重写即可


    <h1 id="-" style="margin: 20px 0px 10px; padding: 0px; font-weight: bold; color: black; font-size: 24px; border-bottom: 2px solid #aaaaaa;">三.单例模式的缺点
    <ul style="margin: 1.2em 0px; padding-left: 2em; list-style-type: square; font-size: 16px;">
    <li style="margin: 0.5em 0px; font-size: 16px;">
    <p style="margin: 0.5em 0px !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">全局变量可能在某处被修改,但开发人员仍然认为他们没有发生变化

  •  :
        _shared_state={}
         :
            self.x=
            self.__dict__=self._shared_state
    

    a=Monostate()
    b=Monostate()
    b.x=<span class="hljs-number" style="color: #ffc58f;">5
    print(a)<span class="hljs-comment" style="color: #7285b7;">#<main.Monostate object at 0x000001C267714B38>
    print(b)<span class="hljs-comment" style="color: #7285b7;">#<main.Monostate object at 0x000001C267714B00>
    print(a.x)<span class="hljs-comment" style="color: #7285b7;">#5
    a.c=<span class="hljs-number" style="color: #ffc58f;">4
    print(b.c)<span class="hljs-comment" style="color: #7285b7;">#4


    <p style="margin: 0px 0px 1.2em !important; font-size: 16px; line-height: 1.75em; padding-right: 0.5em; padding-left: 0.5em;">这里的实现方式为利用类中的dict方法,我感觉是将_shared_state赋给dict后,每个对象的dict的地址都是相同的,所以对象的属性存储的位置都相同,那么一个对象的属性变化,其余的属性也会发生变化。


    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读