我正在寻找一种通用且简单的方法来同步本身不使用异步调用的python类的方法。我想到了一些可能性:首先,在类本身的所有方法上使用装饰器:http: //code.activestate.com/recipes/577105-synchronization-decorator-for-class-methods/。但我不希望更改类,所以其次,使用包装器或子类同步访问所有子类/核心方法。我想也许,有一种通用的方法来同步对 python 对象的访问,这样你就不会意外地错过层次结构中超类的方法(特别是如果它稍后被更改)。因此,第三,您可能可以使用类似于以下内容的通用代理:http://code.activestate.com/recipes/366254-generic-proxy-object-with-beforeafter-method-hooks/ 并为每次访问使用可重入锁。我更喜欢第三种选择。只是让我烦恼的是我没有找到这个食谱。这个解决方案有什么问题还是有更好的解决方案?
EDIT2: 最后一个选项类似于以下代码段,并已使用 codetidy.com/5911/ 进行了测试。测试不是证明它有效,只是一个轻微的指示。由于这不是我的日常编码,如果有经验的人可以检查是否有任何错误,这将有所帮助。
#!/usr/bin/env python
import types
from pprint import pformat
from threading import RLock
class SynchronizeMethodWrapper:
"""
Wrapper object for a method to be called.
"""
def __init__( self, obj, func, name, rlock ):
self.obj, self.func, self.name = obj, func, name
self.rlock = rlock
assert obj is not None
assert func is not None
assert name is not None
def __call__( self, *args, **kwds ):
"""
This method gets called before a method is called to sync access to the core object.
"""
with self.rlock:
rval = self.func(*args, **kwds)
return rval
class SynchronizeProxy(object):
"""
Proxy object that synchronizes access to a core object methods and attributes that don't start with _.
"""
def __init__( self, core ):
self._obj = core
self.rlock = RLock()
def __getattribute__( self, name ):
"""
Return a proxy wrapper object if this is a method call.
"""
if name.startswith('_'):
return object.__getattribute__(self, name)
else:
att = getattr(self._obj, name)
if type(att) is types.MethodType:
return SynchronizeMethodWrapper(self, att, name, object.__getattribute__(self, "rlock"))
else:
return att
def __setitem__( self, key, value ):
"""
Delegate [] syntax.
"""
name = '__setitem__'
with self.rlock:
att = getattr(self._obj, name)
pmeth = SynchronizeMethodWrapper(self, att, name, self.rlock)
pmeth(key, value)
EDIT3:我使用了 SynchronizeProxy,到目前为止它似乎有效。由于此解决方案最接近我的需要,因此我将选择我的答案作为解决方案