Search code examples
pythontwisted

exceptions.AttributeError: Python instance has no attribute 'name'


I am doing Cesare Rocchi's tutorial "How To Create A Socket Based iPhone App and Server" http://www.raywenderlich.com/3932/how-to-create-a-socket-based-iphone-app-and-server#comments

Do I need to define an attribute called 'name' in the "class IphoneChat(Protocol)" or is it inherited from "twisted.internet.protocol?" If it is inherited, how do I access it correctly?

server.py:

from twisted.internet.protocol import Factory, Protocol  
from twisted.internet import reactor
class IphoneChat(Protocol):
    def connectionMade(self):
        self.factory.clients.append(self)
        print "clients are", self.factory.clients

    def connectionLost(self, reason):
        self.factory.clients.remove(self) 

    def dataReceived(self, data):
        a = data.split(':')
        print a 
        if len(a) > 1:
            command = a[0]
            content = a[1]

            msg = ""
            if command == "iam":
                self.name = content
                msg = self.name + "has joined"
            elif command == "msg":
                msg = self.name + ": " + content 
                print msg

            for c in self.factory.clients:
                c.message(msg)

    def message(self, message):
        self.transport.write(message + '\n')

factory = Factory()
factory.protocol = IphoneChat
factory.clients = []
reactor.listenTCP(80, factory)
print "Iphone Chat server started"
reactor.run()

Terminal output:

Iphone Chat server started
...
--- <exception caught here> ---
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/twisted/internet/selectreactor.py", line 150, in _doReadOrWrite
    why = getattr(selectable, method)()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/twisted/internet/tcp.py", line 199, in doRead
    rval = self.protocol.dataReceived(data)
  File "server.py", line 30, in dataReceived
    msg = self.name + ": " + content
exceptions.AttributeError: IphoneChat instance has no attribute 'name'

Problem solving steps so far:


Solution

  • Well the error is quite logical

    if command == "iam":
        self.name = content
        msg = self.name + "has joined"
    elif command == "msg":
        msg = self.name + ": " + content 
        print msg
    

    In the first if clause you assign a value to self.name which may either rely on assumption that self.name exists somewhere, or on assumption that it is new and needs to be declared, but in elif you seem to assume with certainty that self.name already exists, it turns out it doesn't so you get an error.

    I guess your safest option consists of simply adding self.name at the beginning of dataReceived method:

    def dataReceived(self, data):
        self.name = ""
    

    this will get rid of the error. As an alternative you could also add self.name to init method of IphoneChat.If you need self.name in other functions not only in dataReceived then adding init with self.name is the way to go, but from your code it seems you only need it in datareceived so just add it there. Adding self.name in init would look like this:

    class IphoneChat(Protocol):
        def __init__(self):
            self.name = ""
    

    or you can also simply do

    class IphoneChat(Protocol):
        name = ""
    

    and then go on with name instead of self.name.