Reputation: 8088
class Person:
def __init__(self, name):
self.name = name
self.bucket = []
def announce(self, *args):
# ???
pass
def put(self, item):
self.bucket.append(item)
p1 = Person("ya")
p2 = Person("yu")
p1.put("apple")
now I want to somehow announce to all Person() objects that I have an apple in my bucket, they should put one apple in their bucket too if they want.
Upvotes: 1
Views: 1021
Reputation: 25094
Implementing the observer-pattern in python is quite simple, The basic idea "I want Object A, object B, Object C to get notifications from a specified messaging Object". Therefore you somehow have to connect them, in observer Pattern this process is called "subscription". So your Object A, B, C (Observers) are subscribing to the Object that delivers messages (Subject) This example is a basic implementation. I didn't addapt it to your code, but alice and bob would be Persons in your case.
class Mailbox :
def __init__(self, ownersName):
self.owner = ownersName
self.messages = []
self.newMessageObservers = []
def deliverMessage(self, message):
self.messages.append(message)
for notifyNewMessage in self.newMessageObservers:
notifyNewMessage(message, self.owner)
def subscribe(self, observer):
self.newMessageObservers.append(observer)
class MailboxObserver :
def __init__(self, observerName):
self.name = observerName
def newMessageHandler(self, contents, owner):
print self.name + " observed a new message in " +\
owner + "'s mailbox"
print "The message said: " + contents
# create the observers
alice = MailboxObserver("alice")
bob = MailboxObserver("bob")
# create a mailbox
alicesMailbox = Mailbox("alice")
# have bob and alice subscribe to alice's mailbox
# registering their 'newMessageHandler' method
alicesMailbox.subscribe(bob.newMessageHandler)
alicesMailbox.subscribe(alice.newMessageHandler)
# put a new message into alice's mailbox
alicesMailbox.deliverMessage("Hello, world!")
source: http://www.philipuren.com/serendipity/index.php?/archives/4-Simple-Observer-Pattern-in-Python.html
Upvotes: 1
Reputation: 23731
Simple implementation could be:
class Person:
persons = set()
def __init__(self, name):
self.name = name
self.bucket = []
self.persons.add(self)
def announce(self, msg):
print("[{}]: {}".format(self.name,msg))
@classmethod
def broadcast(cls, person, msg):
for p in cls.persons:
if not p is person:
p.announce(msg)
def put(self, item):
self.bucket.append(item)
self.broadcast(self, '{}: got {} in my bucket!'.format(self.name, item))
p1 = Person("ya")
p2 = Person("yu")
p1.put("apple")
Person.broadcast(None, "Hey! Everybody can broadcast message!")
Output:
[yu]: "ya: got apple in my bucket!
[ya]: Hey! Everybody can broadcast message!
[yu]: Hey! Everybody can broadcast message!
That implementation lacks in
deregister
implementationPerson
and it's subclass can be informedMaybe is better you implement an Observer pattern better than that simple one.
Upvotes: 3
Reputation: 4609
Just keep a normal variable in your class (Not a member), and update it whenever you want to "announce" something to all classes.
class Person:
bApple = False
def __init__(self, name):
self.name = name
self.bucket = []
def announce(self, *args):
# ???
pass
def put(self, item):
self.bucket.append(item)
def hasApple(self):
if Person.bApple:
return "True"
else:
return "False"
p1 = Person("ya")
p2 = Person("yu")
p1.put("apple")
print "p1 has Apple? " + p1.hasApple()
print "p2 has Apple? " + p2.hasApple()
Person.bApple = True
print "p1 has Apple? " + p1.hasApple()
print "p2 has Apple? " + p2.hasApple()
Upvotes: 0