yayu
yayu

Reputation: 8088

how to "broadcast" a message to all objects of a class?

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

Answers (3)

user1767754
user1767754

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

Michele d'Amico
Michele d'Amico

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

  • No deregister implementation
  • No thread save
  • Just Person and it's subclass can be informed
  • It is just a toy, you need to adapt it to your real case

Maybe is better you implement an Observer pattern better than that simple one.

Upvotes: 3

Kartik Anand
Kartik Anand

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

Related Questions