jacob30
jacob30

Reputation: 151

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:

Upvotes: 1

Views: 4363

Answers (2)

Ectac
Ectac

Reputation: 95

You may be parsing the wrong text.

The article says to type “aim:cesare” and then "msg:hi" but your program doesn't know how to handle "aim:" as a command. So when you run "msg:hi" afterwards, self.name would not have a value. It looks like it was a typo from the article's author. The following commands should work:

"aim:cesare"

=> cesare

     has joined

"msg:hi"

=> cesare

   : hi

Upvotes: 0

Pawel Miech
Pawel Miech

Reputation: 7822

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.

Upvotes: 2

Related Questions