我有一个简单的聊天应用程序与Python中的服务器和客户端代码。在服务器端,类Client定义以下
class Client(object):
def __init__(self, socket, address):
self.sock = socket
self.addr = address
self.room = None
self.name = None
self._is_online = True
thread = threading.Thread(target=self.run, args=())
thread.daemon = True
thread.start()
如您所见,服务器将每个客户端作为不同的线程处理。在主线程上,服务器以始终为真的循环运行
while True:
(ready_to_read, _, _) = select.select([server_sckt] + [Client.sock for Client in clients], [], [])
for connection in ready_to_read:
if connection == server_sckt:
(connection, address) = server_sckt.accept()
clients.append( Client(connection, address) )
clients
是包含所有Client
个对象的列表。问题出现在第二次循环迭代中。
Traceback (most recent call last):
File "servidor_class.py", line 215, in <module>
clients.append( Client(connection, address) )
TypeError: 'Client' object is not callable
所以很明显我没有得到pythonic OOP方式来声明每个实例。
我查看了另一个相关问题:
但我仍然没有看到我的错误,确定它在我面前。没有附加到列表似乎工作,但主要服务器功能,如向所有在线人发送消息或检查用户名是否已经使用不起作用。
答案 0 :(得分:3)
在Python 2中,列表推导泄漏了控制变量:请参阅this question
问题是上面的几行,其中异常实际发生在选择行
# | Here
# v
(ready_to_read, _, _) = select.select([server_sckt] + [Client.sock for Client in clients], [], [])
在列表理解中,您重新定义了Client
的含义。它成为Client
类的一个实例。因此,当您尝试使用现有实例而不是类创建另一个实例时,会引发异常。
将列表理解部分更改为
# | notice the lower case.
# v
[client.sock for client in clients]
除了Client