2013-08-04 42 views
1

我做切薩雷羅基的教程「如何創建基於套接字的iPhone應用程序和服務器」 http://www.raywenderlich.com/3932/how-to-create-a-socket-based-iphone-app-and-server#commentsexceptions.AttributeError:Python實例沒有屬性「名」

我需要定義一個名爲「名稱」中的一個屬性「IphoneChat類(協議)」還是繼承自「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

這是不是真的你的問題是什麼,但它是你的問題稍後會用這個代碼命中:請注意,您不能依賴'dataReceived'來傳遞整個消息。請參閱此常見問題解答:http://twistedmatrix.com/trac/wiki/FrequentlyAskedQuestions#Whyisprotocol.dataReceivedcalledwithonlylypartofthedataatacalledtransport.writewith – Glyph

回答

2

好吧,如果你子句指定值self.name其可能是依賴於假設self.name存在於某個地方,或者在假設的錯誤是很合乎邏輯的

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

在第一個,它是新的,需要聲明,但是在elif中,您似乎完全肯定self.name已經存在,事實證明它並不會導致錯誤。

我猜你最安全的選擇由簡單地dataReceived方法的開頭添加self.name:

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

這將擺脫錯誤的。作爲替代方案,您還可以將self.name添加到IphoneChat的init方法中。如果您在其他函數中需要self.name,而不僅僅是在dataReceived中,那麼使用self.name添加init是要走的路,但是從您的代碼看起來您​​只是在數據採集中需要它,所以只需將它添加到那裏。在初始化添加self.name應該是這樣的:

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

,或者你也可以簡單地做

class IphoneChat(Protocol): 
    name = "" 

,然後再與名代替self.name。

0

您可能會解析錯誤的文本。

這篇文章說輸入「aim:cesare」然後「msg:hi」,但是你的程序不知道如何處理「aim:」作爲命令。所以當你以後運行「msg:hi」時,self.name不會有值。看起來這是文章作者的錯字。下面的命令應該工作:

「的目標:凱撒」

=> cesare 

    has joined 

「消息:喜」

=> cesare 

    : hi 
相關問題