eval, .
:
>>> d = dict()
>>> inspect.ismethod(d.__setitem__)
, ismethod:
true, , Python.
, C ( .NET, Java, .. Python) , Python.
, , callable inspect.isroutine .
, , , , eval :
self.__cmp__ = types.MethodType(lambda self, *args, **kwargs: self.atomize(0, *args, **kwargs) self)
... , .
eval . , setattr. lambda s. def; - , , lambda, , .
, , . (, , , - , .) __getattr__. ( , ... -, , , , , , . , .)
, , , , :
class atomicObject(object):
def __init__(self, obj):
self.lock = threading.Lock()
self.obj = obj
def __getattr__(self, name):
attr = getattr(self.obj, name)
print(attr)
if callable(attr):
def atomized(*args, **kwargs):
with self.lock:
attr(*args, **kwargs)
return atomized
return attr
, . :
>>> d = atomicObject(dict())
>>> d.update({'a': 4})
>>> d['b'] = 5
TypeError: 'atomicObject' object does not support item assignment
? __setitem__, :
>>> d.__setitem__
<method-wrapper '__setitem__' of dict object at 0x100706830>
>>> d.__setitem__('b', 5)
, , docs, , . atomicObject __setitem__.
, , __str__ __repr__ object:
>>> d
<__main__.atomicObject object at 0x100714690>
>>> print(d)
<__main__.atomicObject object at 0x100714690>
>>> d.obj
{'a': 4, 'b': 5}
, - , - , :
>>> AtomicDict = make_atomic_wrapper(dict)
>>> d = AtomicDict()
, ... , .
:
d = AtomicDict()
d['abc'] = 0
d['abc'] += 1
. __getitem__, __setitem__.
, , d . 20 , d['abc'] += 1 . , __getitem__, 0. , __setitem__, 1.
. 2000. 125.