我正在做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'
到目前为止解决问题的步骤:
答案 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