1

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

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

服务器.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'

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

4

2 回答 2

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 方法中。如果您不仅在 dataReceived 中需要 self.name 在其他函数中,那么添加带有 self.name 的 init 是要走的路,但从您的代码看来,您只有需要它在 datareceived 中,所以只需将它添加到那里。在 init 中添加 self.name 如下所示:

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

或者你也可以简单地做

class IphoneChat(Protocol):
    name = ""

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

于 2013-08-04T10:32:58.883 回答
0

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

文章说要输入“aim:cesare”,然后输入“msg:hi”,但您的程序不知道如何将“aim:”作为命令处理。因此,当您之后运行“msg:hi”时,self.name 将没有值。看来是文章作者打错字了。以下命令应该可以工作:

“目标:切萨雷”

=> cesare

     has joined

“味精:嗨”

=> cesare

   : hi
于 2014-07-12T18:19:15.083 回答