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