如何在Python中实现循环中的类

时间:2017-05-17 17:14:14

标签: python

我有一个简单的聊天应用程序与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方式来声明每个实例。

我查看了另一个相关问题:

  1. Creating object instances in a loop with independent handling
  2. Python creating multiple instances for a single object/class
  3. 但我仍然没有看到我的错误,确定它在我面前。没有附加到列表似乎工作,但主要服务器功能,如向所有在线人发送消息或检查用户名是否已经使用不起作用。

1 个答案:

答案 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

之外的任何其他内容