exceptions.AttributeError:Python实例没有属性'name'

时间:2013-08-04 09:57:36

标签: python twisted

我正在做Cesare Rocchi的教程“如何创建基于套接字的iPhone应用和服务器”http://www.raywenderlich.com/3932/how-to-create-a-socket-based-iphone-app-and-server#comments

我是否需要在“IphoneChat(Protocol)”类中定义一个名为“name”的属性,还是继承自“twisted.internet.protocol?”如果它是继承的,我该如何正确访问它?

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()

终端输出:

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'

到目前为止解决问题的步骤:

2 个答案:

答案 0 :(得分:2)

错误是非常合乎逻辑的

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

在第一个if子句中,为self.name赋值,这可能依赖于self.name存在于某处的假设,或者假设它是新的并且需要声明,但是在elif中你似乎假设确定self.name已经存在,事实证明它不会导致错误。

我想你最安全的选择只需在dataReceived方法的开头添加self.name:

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

这将摆脱错误。作为替代方案,您还可以将self.name添加到IphoneChat的init方法。如果您在其他函数中需要self.name,不仅仅是在dataReceived中,那么添加带有self.name的init是可行的方法,但是从您的代码看来,它似乎只是需要它在datareceived中,所以只需将其添加到那里。在init中添加self.name将如下所示:

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

或者你也可以简单地做

class IphoneChat(Protocol):
    name = ""

然后继续使用name而不是self.name。

答案 1 :(得分:0)

您可能正在解析错误的文本。

文章说要输入“目标:cesare”然后&#34; msg:hi&#34;但是你的程序并不知道如何处理&#34;目标:&#34;作为一个命令。所以当你运行&#34; msg:hi&#34;之后,self.name将没有值。看起来这是文章作者的错字。以下命令应该有效:

&#34;宗旨:切萨雷&#34;

=> cesare

     has joined

&#34; MSG:喜&#34;

=> cesare

   : hi