class - Understanding Borg Singleton Pattern in Python -
i saw borg singleton pattern code couldn't head around how new members add singleton object gets appended __shared_state = {}
dictionary.
here singleton code
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 another_borg child = child() borg.only_one_var = "i'm 1 var" print child.only_one_var
so question when object borg.only_one_var
created how appended _shared_state
dictionary
by default each instance gets own dictionary , hence assigning attribute 1 instance doesn't affect other instances.
but can make instance's dictionary point new dict , when internally used there on store items.
in case every time instance being created you're assigning dictionary point borg. _shared_state
. hence, instances use same dict fetch , set attributes.
it's equivalent to:
shared = {} class a(object): def __init__(self): self.__dict__ = shared
demo:
>>> ins = [a() _ in range(5)] >>> ins[0].x = 100 >>> in ins: ... print(i.x) ... 100 100 100 100 100 >>> shared {'x': 100}
in cpython assignment of new dictionary __dict__
happens inside pyobject_genericsetdict
:
int pyobject_genericsetdict(pyobject *obj, pyobject *value, void *context) { pyobject **dictptr = _pyobject_getdictptr(obj); ... if (!pydict_check(value)) { pyerr_format(pyexc_typeerror, "__dict__ must set dictionary, " "not '%.200s'", py_type(value)->tp_name); return -1; } py_incref(value); py_xsetref(*dictptr, value); # set dict point new dict return 0; }
note since arrival of key-sharing dictionaries in python 3.3+ dictionaries of instances of same class can share internal state save space.
Comments
Post a Comment