Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 两个课程的区别是什么?它们的工作方式不同吗?_Python_Python 3.x_Class_Inheritance_Singleton - Fatal编程技术网

Python 两个课程的区别是什么?它们的工作方式不同吗?

Python 两个课程的区别是什么?它们的工作方式不同吗?,python,python-3.x,class,inheritance,singleton,Python,Python 3.x,Class,Inheritance,Singleton,这两种Singleton实现之间的区别是什么。在父类中创建变量_实例是否使其工作方式与第二个类不同 class SingletonA(object): _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = object.__new__(cls, *args, **kwargs) return cls

这两种Singleton实现之间的区别是什么。在父类中创建变量_实例是否使其工作方式与第二个类不同

class SingletonA(object):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = object.__new__(cls, *args, **kwargs)
        return cls._instance


class SingletonB(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            cls._instance = object.__new__(cls, *args, **kwargs)
        return cls._instance


# sample usage
class A(SingletonA):
    pass


print(A() == A()) #True

对于张贴的代码,没有区别

但是,如果您的子类实现了或,则第一个示例将失败,因为
不是self.\u instance
可能返回
True
,即使已设置实例。如果self.\u实例为None,则确实要使用

>>> class AlwaysFalse(object):
...     def __bool__(self): return False
...
>>> if not AlwaysFalse():
...     print("It doesn't exist? Should we create a new one?")
...
It doesn't exist? Should we create a new one?
>>> AlwaysFalse() is None
False
除此之外,这些差异只是表面上的

您还希望使用身份测试来检查单例实现是否正常工作;子类可以实现并返回
True
,即使这两个对象是不同的(因此不是单例):


对于张贴的代码,没有区别

但是,如果您的子类实现了或,则第一个示例将失败,因为
不是self.\u instance
可能返回
True
,即使已设置实例。如果self.\u实例为None,则确实要使用

>>> class AlwaysFalse(object):
...     def __bool__(self): return False
...
>>> if not AlwaysFalse():
...     print("It doesn't exist? Should we create a new one?")
...
It doesn't exist? Should we create a new one?
>>> AlwaysFalse() is None
False
除此之外,这些差异只是表面上的

您还希望使用身份测试来检查单例实现是否正常工作;子类可以实现并返回
True
,即使这两个对象是不同的(因此不是单例):


同意@Martijin Pieters的回答

此外,提供另一种实现单例的方法,称为Borg,它们共享相同的状态:

class Borg:
    _shared_state = {}
    def __new__(cls, *args, **kwargs):
        obj = super(Borg, cls).__new__(cls, *args, **kwargs)
        obj.__dict__ = cls._shared_state
        return obj

class S1(Borg):
    pass

class S2(Borg):
    pass

assert S1() is not S1()
S1().v = 1
assert S1().v == S1().v
assert S1().v == S2().v


class S3(Borg):
    # if want to have a different state
    _shared_state = {}
    pass

S3().v = 2
assert S3().v != S1().v

同意@Martijin Pieters的回答

此外,提供另一种实现单例的方法,称为Borg,它们共享相同的状态:

class Borg:
    _shared_state = {}
    def __new__(cls, *args, **kwargs):
        obj = super(Borg, cls).__new__(cls, *args, **kwargs)
        obj.__dict__ = cls._shared_state
        return obj

class S1(Borg):
    pass

class S2(Borg):
    pass

assert S1() is not S1()
S1().v = 1
assert S1().v == S1().v
assert S1().v == S2().v


class S3(Borg):
    # if want to have a different state
    _shared_state = {}
    pass

S3().v = 2
assert S3().v != S1().v

第二个选项在需要时创建
\u实例
变量,因此第二种方法更节省空间。运行时也可能有利于第二个选项,因为将值与
True
(或
None
)进行比较比仅查找变量需要更多的时间。第二个选项在需要时创建
\u实例
变量,因此使用第二种方法会更节省空间。运行时也可能有利于第二个选项,因为将值与
True
(或
None
)进行比较比仅查找变量需要更多的时间