2017-07-10 54 views
1

有以下服務器代碼(我定義從插座繼承的類,我試圖使用類調用客戶端插座上的發送方法):類型錯誤不斷變化的Socket對象的__class__屬性

import socket 

class LogSocket(socket.socket): 
    def send(self, data): 
     print("Sending {0} to {1}".format(
      data, self.getpeername()[0])) 
     super().send(data) 

def respond(client): 
    response = input("Enter a value: ") 
    client.send(bytes(response, 'utf8')) 
    client.close() 

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
server.bind(('',2401)) 
server.listen(1) 
try: 
    while True: 
     client, addr = server.accept() 
     client.__class__ = LogSocket 
     respond(client) 
finally: 
    server.close() 

客戶端代碼是:

import socket 

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
client.connect(('localhost', 2401)) 
print("Received: {0}".format(client.recv(1024))) 
client.close() 

當我運行上面的代碼中,服務器崩潰,並顯示錯誤:

Traceback (most recent call last): 
    File "10_04_server.py", line 20, in <module> 
    client.__class__ = LogSocket 
TypeError: __class__ assignment: 'LogSocket' object layout differs from 'socket' 

這個錯誤是什麼意思?爲什麼會發生?

回答

1

設置__slots__屬性(),而這將工作:

class LogSocket(socket.socket): 
    __slots__ =() 
    def send(self, data): 
     print("Sending {0} to {1}".format(
      data, self.getpeername()[0])) 
     super().send(data) 

relevant pieces of documentation是:

The action of a __slots__ declaration is limited to the class where it is defined. As a result, subclasses will have a __dict__ unless they also define __slots__ (which must only contain names of any additional slots).

而且

__class__ assignment works only if both classes have the same __slots__ .

+0

由於它的工作。該錯誤消息不是很有幫助。 – debashish

+0

當我們分配一個空值時,套接字類有一個非空的'__slots__'值。如果這些類有不同的'__slots__',那麼'__class__'賦值如何工作? – debashish

+0

再次閱讀第一個文檔片段。子類中的__slots__是_additional_ slots。 – Eric

相關問題