理解Python中的Borg单例模式
我看到了这个Borg Singleton模式代码,但我无法理解我添加到Singleton对象的新成员是如何附加到理解Python中的Borg单例模式,python,class,oop,design-patterns,Python,Class,Oop,Design Patterns,我看到了这个Borg Singleton模式代码,但我无法理解我添加到Singleton对象的新成员是如何附加到\uuuuuShared\uState={}字典中的 这是单例代码 class Borg(object): _shared_state = {} def __new__(cls,*args,**kwargs): obj = super(Borg,cls).__new__(cls,*args,**kwargs) obj.__dict__
\uuuuuShared\uState={}
字典中的
这是单例代码
class Borg(object):
_shared_state = {}
def __new__(cls,*args,**kwargs):
obj = super(Borg,cls).__new__(cls,*args,**kwargs)
obj.__dict__ = cls._shared_state
return obj
class Child(Borg):
pass
if __name__ == '__main__':
borg = Borg()
another_borg = Borg()
print borg is another_borg
child = Child()
borg.only_one_var = "I'm the only one var"
print child.only_one_var
因此,我的问题是,当对象
borg.only_one_var
被创建时,它是如何被附加到\u shared_state
字典的?在一个类外上下文字典的简单情况下,您可能知道,您可以附加新的键值对,如:
dic = {}
dic['first'] = 1
print(dic)
>>> {'first': 1}
在您的例子中,您将\u共享\u状态
字典分配给对象的字典obj.\uu dict\uu
。所以现在,obj.\uuuuu dict\uuuuuu
是对\u共享\u状态
字典的引用
当您在obj
实例上使用该点路径表示法时,实际上会将一个键值对附加到它的字典中,从而附加到\u共享\u状态
字典中
因为这个类是一个单例,所以所有其他实例的字典将引用相同的
\u共享\u状态
字典。因此,默认情况下,所有实例都将具有“相同的”\uuuu dict\uuuu
,因此,为一个实例分配属性不会影响其他实例
但您可以使实例的字典指向一个新的dict,当您在内部这样做时,它将从此处开始用于存储项
在您的例子中,每次创建实例时,您都将其字典分配给指向Borg的对象_共享状态
。因此,它的所有实例都将使用相同的dict来获取和设置属性
这基本上相当于:
shared = {}
class A(object):
def __init__(self):
self.__dict__ = shared
演示:
>>> ins = [A() for _ in range(5)]
>>> ins[0].x = 100
>>> for i in ins:
... print(i.x)
...
100
100
100
100
100
>>> shared
{'x': 100}
在CPython中,将新词典分配给\uuuu dict\uuu
发生在:
请注意,由于Python 3.3+中的出现,同一类实例的字典可以共享一些内部状态以节省空间。不起作用<代码>类型错误:无法设置内置/扩展类型“dict”的属性。谢谢。写字典和思考对象。愚蠢的我:)
int
PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context)
{
PyObject **dictptr = _PyObject_GetDictPtr(obj);
...
if (!PyDict_Check(value)) {
PyErr_Format(PyExc_TypeError,
"__dict__ must be set to a dictionary, "
"not a '%.200s'", Py_TYPE(value)->tp_name);
return -1;
}
Py_INCREF(value);
Py_XSETREF(*dictptr, value); # Set the dict to point to new dict
return 0;
}