carfield.com.hkObserver.py2001-12-26T16:00:00Z2001-12-26T16:00:00Z<br/><TEXTAREA name="code" class="py" rows="16" cols="100">#: util:Observer.py
# Class support for "observer" pattern.
from Synchronization import *
class Observer:
def update(observable, arg):
'''Called when the observed object is
modified. You call an Observable object's
notifyObservers method to notify all the
object's observers of the change.'''
pass
class Observable(Synchronization):
def __init__(self):
self.obs = []
self.changed = 0
Synchronization.__init__(self)
def addObserver(self, observer):
if observer not in self.obs:
self.obs.append(observer)
def deleteObserver(self, observer):
self.obs.remove(observer)
def notifyObservers(self, arg = None):
'''If 'changed' indicates that this object
has changed, notify all its observers, then
call clearChanged(). Each observer has its
update() called with two arguments: this
observable object and the generic 'arg'.'''
self.mutex.acquire()
try:
if not self.changed: return
# Make a local copy in case of synchronous
# additions of observers:
localArray = self.obs[:]
self.clearChanged()
finally:
self.mutex.release()
# Updating is not required to be synchronized:
for observer in localArray:
observer.update(self, arg)
def deleteObservers(self): self.obs = []
def setChanged(self): self.changed = 1
def clearChanged(self): self.changed = 0
def hasChanged(self): return self.changed
def countObservers(self): return len(self.obs)
synchronize(Observable,
"addObserver deleteObserver deleteObservers " +
"setChanged clearChanged hasChanged " +
"countObservers")
#:~</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2001-12-26T16:00:00ZSynchronization.py2001-12-26T16:00:00Z2001-12-26T16:00:00Z<br/><TEXTAREA name="code" class="py" rows="16" cols="100">#: util:Synchronization.py
'''Simple emulation of Java's 'synchronized'
keyword, from Peter Norvig.'''
import threading
def synchronized(method):
def f(*args):
self = args[0]
self.mutex.acquire();
# print method.__name__, 'acquired'
try:
return apply(method, args)
finally:
self.mutex.release();
# print method.__name__, 'released'
return f
def synchronize(klass, names=None):
"""Synchronize methods in the given class.
Only synchronize the methods whose names are
given, or all methods if names=None."""
if type(names)==type(''): names = names.split()
for (name, val) in klass.__dict__.items():
if callable(val) and name != '__init__' and \
(names == None or name in names):
# print "synchronizing", name
klass.__dict__[name] = synchronized(val)
# You can create your own self.mutex, or inherit
# from this class:
class Synchronization:
def __init__(self):
self.mutex = threading.RLock()
#:~</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2001-12-26T16:00:00ZTestSynchronization.py2001-12-26T16:00:00Z2001-12-26T16:00:00Z<br/><TEXTAREA name="code" class="py" rows="16" cols="100">#: util:TestSynchronization.py
from Synchronization import *
# To use for a method:
class C(Synchronization):
def __init__(self):
Synchronization.__init__(self)
self.data = 1
def m(self):
self.data += 1
return self.data
m = synchronized(m)
def f(self): return 47
def g(self): return 'spam'
# So m is synchronized, f and g are not.
c = C()
# On the class level:
class D(C):
def __init__(self):
C.__init__(self)
# You must override an un-synchronized method
# in order to synchronize it (just like Java):
def f(self): C.f(self)
# Synchronize every (defined) method in the class:
synchronize(D)
d = D()
d.f() # Synchronized
d.g() # Not synchronized
d.m() # Synchronized (in the base class)
class E(C):
def __init__(self):
C.__init__(self)
def m(self): C.m(self)
def g(self): C.g(self)
def f(self): C.f(self)
# Only synchronizes m and g. Note that m ends up
# being doubly-wrapped in synchronization, which
# doesn't hurt anything but is inefficient:
synchronize(E, 'm g')
e = E()
e.f()
e.g()
e.m()
#:~</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2001-12-26T16:00:00Z