So, I’m trying to code an observer pattern in Python. Main method:
import Subject as Subj import ConcreteStateA as Obs Newsletter = Subj.Subject Paul = Obs Sara = Obs Julien = Obs print(Paul) print(Sara) Newsletter().addObserver(Paul) Newsletter().addObserver(Sara) Newsletter().addObserver(Julien) Newsletter().notifyObservers("Bald ist Weihnachten!") Newsletter().removeObserver(Paul) Newsletter().notifyObservers("Der Nikolaus steht vor der Tür.")
class Subject: def __init__(self): self.ObserverList = [] def addObserver(self, Observer): self.ObserverList.append(Observer) def removeObserver(self, Observer): self.ObserverList.remove(Observer) def notifyObservers(message, self): print("test") for obs in self.ObserverList: print("Notified Observer") obs.update(message)
import Observer class ConcreteStateA(Observer.Observer): def Handle(msg, self): print(self.__name__ + "has received a message: " +self.msg) print(msg)
As far as I understand the self parameter, it references to it’s own instance. So if I type it in a Subject object, it would reference to that. Yet I get this error message:
AttributeError: 'str' object has no attribute 'ObserverList'
I don’t understand why it references to the message variable in an Subject method, shouldn’t it reference to the Newsletter (Subject class) object?
I tried to google my problem and read into the self parameter, yet without any success. Everything I read seemed to support my theory, that the Newsletter object should be referenced, not the string message.
As I am fairly new to python there might be some other problems, i would be happy if you have other tips too :)
Advertisement
Answer
def notifyObservers(message, self): print("test") for obs in self.ObserverList: print("Notified Observer") obs.update(message)
The mistake is the way you define your parameters here. The fact is the first parameter will always be what you know as self
– the Object. So by having a message as your first parameter, message will be used as the parameter for your object. e.g.: you could do message.ObserverList
. Make sure to always have self
as the first parameter.
So..
def notifyObservers(self, message): print("test") for obs in self.ObserverList: print("Notified Observer") obs.update(message)
and
class ConcreteStateA(Observer.Observer): def Handle(self, msg): print(self.__name__ + "has received a message: " +self.msg) print(msg)
should do the trick