RELEASED Python 2.4, alpha 2

Casey Duncan casey at zope.com
Thu Aug 5 13:32:53 EDT 2004


On Thu, 5 Aug 2004 18:51:08 +0200
Heiko Wundram <heikowu at ceosg.de> wrote:

[..]
> Think of the following: (old style)
> 
> class x(object):
> 	def __init__(self):
> 		self.lock = threading.RLock()
> 
> 	def synchronized_method(self):
> 		self.lock.acquire()
> 		try:
> 			<bla>
> 		finally:
> 			self.lock.release()
> 
> That's just plain horrible compared to what @ decorators can do:

Seems clear to me.
> 
> class x(object):
> 	synchronized = InstanceSynchronizer()
> 
> 	@synchronized
> 	def synchronized_method(self):
> 		<bla>
> 
> Writing the InstanceSynchronizer is pretty easy too:
> 
> class InstanceSynchronizer(object):
> 
> 	def __init__(self):
> 		self._locks = {}
> 		self._refs = {}
> 
> 	def _delete_ref(self,ref):
> 		del self._locks[self._refs[id(ref)][1]]
> 		del self._refs[id(ref)]
> 
> 	def __call__(self,f):
> 		def fsyn(fself,*args,**kwargs):
> 			try:
> 				lock = self._locks[id(fself)]
> 			except KeyError:
> 				lock = threading.RLock()
> 				fselfref = weakref.ref(fself,self._delete_ref)
> 				self._locks[id(fself)] = lock
> 				self._refs[id(fselfref)] = (fselfref,id(fself))
> 			lock.acquire()
> 			try:
> 				return f(fself,*args,**kwargs)
> 			finally:
> 				lock.release()
> 		return fsyn

I will grant you that InstanceSynchronizer is reusable, but look at the
volume of code here compared to the first example. I find the latter
much more complex. Regardless, decorators don't really make this pattern
possible, you could just as easily do this in 2.3:

class x(object):
    synchronized = InstanceSynchronizer()

    def method(self):
        <bla>
    method = synchronized(method)

The primary argument against this is that the rebinding is hidden down
after the method body. I personally don't find that to be a problem, and
the advantage is that it is neither a new concept nor a new syntax for
people to learn and understand. It simply leverages what is already
there and is nice and explicit.

[..] 
> Now tell me that using decorators to do synchronization isn't a lot
> easier to read than the first (old) example is, and also less
> error-prone (resp. acquiring/releasing locks properly and without
> deadlocks).

I don't disagree that it is better and more general than your first
example, however, a better and more general technique to do this already
existed before the new decorator syntax.

I just don't feel that the superficial gain of moving the declaration
above the method definition is worth the added complexity to the
language.

-Casey




More information about the Python-list mailing list