求助一个关于python 单例的问题

zxytcjj 2018-04-27 02:47:44

# -*- coding:utf-8 -*-

#因为__new__在__init__前被执行,利用__new__实现单例

#创建过的单例带有属性__instance
class Singleton1(object):
def __new__(cls, *args, **kwargs):
if not hasattr(cls,'__instance'):
cls.__instance = super(Singleton1, cls).__new__(cls, *args, **kwargs)
return cls.__instance

#利用__dict__来引用同一个字典
class Singleton2(object):
_state = {}
def __new__(cls, *args, **kwargs):
ob = super(Singleton2, cls).__new__(cls, *args, **kwargs)
ob.__dict__ = cls._state
return ob

#利用元类在创建方法时用__metaclass__来创建
class Singleton3(type):

def __new__(cls, name, bases, dct):
if not hasattr(cls, '__instance'):
cls.__instance = super(Singleton3, cls).__new__(cls, name, bases, dct)
return cls.__instance

#利用装饰器
def singleton4(cls, *args, **kwargs):
instances = {}
def _single():
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return _single

class Myclass1(Singleton1):
a = 1

class Myclass2(Singleton2):
a = 2

class Myclass3(object):
__metaclass__ = Singleton3
a = 3

@singleton4
class Myclass4(object):
a = 4

if __name__ == "__main__":
s1 = Myclass1()
s2 = Myclass1()
s1.a = 44
print s2.a

s3 = Myclass2()
s4 = Myclass2()
s3.a = 44
print s4.a

s5 = Myclass3()
s6 = Myclass3()
s5.a = 44
print s6.a

s7 = Myclass4()
s8 = Myclass4()
s7.a = 44
print s8.a

四种单例的实现方法,运行结果如下
1
44
3
44

想问一下,为什么第一种和第三种,单例的变量并没有全局化呢?
...全文
790 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
混沌鳄鱼 2018-04-27
  • 打赏
  • 举报
回复
第一个用__new__实现的单例类不能再次继承,必须要直接实例化,不然__new__方法失效。 第三个你实现不是元类,你基本上知道什么是元类。 元类就是 实例化后 返回一个类。所以元类都是从type继承的。 改成下面这样就可以了


# -*- coding:utf-8 -*-

# 因为__new__在__init__前被执行,利用__new__实现单例
# 创建过的单例带有属性__instance
class Singleton1(object):
    """不可以被再继承,不然__new__方法失效"""
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls,'_instance'):
            cls._instance = super(Singleton1, cls).__new__(cls, *args, **kwargs)
        return cls._instance


# 利用__dict__来引用同一个字典
class Singleton2(object):
    _state = {}

    def __new__(cls, *args, **kwargs):
        ob = super(Singleton2, cls).__new__(cls, *args, **kwargs)
        ob.__dict__ = cls._state
        return ob


# 利用元类在创建方法时用__metaclass__来创建
class Singleton3(type):
    def __init__(self, *args, **kwargs):
        self.__instance = None
        super(Singleton3, self).__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        if self.__instance is None:
            self.__instance = super(Singleton3, self).__call__(*args, **kwargs)
        return self.__instance


# 利用装饰器
def singleton4(cls, *args, **kwargs):
    instances = {}

    def _single():
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return _single


class Myclass1(Singleton1):
    a = 1


class Myclass2(Singleton2):
    a = 2


class Myclass3(object):
    __metaclass__ = Singleton3
    a = 3


@singleton4
class Myclass4(object):
    a = 4


s1 = Singleton1()
s2 = Singleton1()
s1.a = 44
print(s2.a)

s3 = Myclass2()
s4 = Myclass2()
s3.a = 44
print(s4.a)

s5 = Myclass3()
s6 = Myclass3()
s5.a = 44
print(s6.a)

s7 = Myclass4()
s8 = Myclass4()
s7.a = 44
print(s8.a)




混沌鳄鱼 2018-04-27
  • 打赏
  • 举报
回复
忘记说了,你的第一个 return cls._instance 多缩进了一层。

37,719

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧