我想创建一个类,将数据从websocket传输到udp套接字。
此代码使用simple-websocket-server模块来实现websocket服务器。
因此,我试图将udp套接字添加为类属性,但会引发错误。
我该如何解决?
请注意,我知道当DataWebSocket对象传递给SimpleSSLWebSocketServer时,此错误能够避免使用闭包。
但是我想尝试对udp套接字进行嵌入式,并且我想了解python中的class属性。
这是代码:
from SimpleWebSocketServer import WebSocket, SimpleSSLWebSocketServer, SimpleWebSocketServer
import multiprocessing
from multiprocessing.managers import BaseManager
import ssl
import signal
import sys
import socket
import os.path
import traceback
class DataWebSocket(WebSocket):
def __new__(cls, cls_name, cls_bases, cls_dict):
try:
super().__new__(cls, cls_name, cls_bases, cls_dict)
cls.udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # add udp socket as a class attribute (not instance attribute)
cls.udp_sock.setblocking(False)
cls.udp_sock.bind(("127.0.0.1", 6666))
print("cls")
return cls
except:
t, mes, tb = sys.exc_info()
print(traceback.format_exception(t, mes, tb))
return cls
def __init__(self, server, sock, address):
try:
super().__init__(server, sock, address)
except:
t, mes, tb = sys.exc_info()
print(traceback.format_exception(t, mes, tb))
def handleMessage(self):
try:
if isinstance(self.data, str):
data = self.data.encode("utf-8")
else:
data = self.data
self.udp_sock.sendto(data, ("127.0.0.1", 7774))
print("raw_data is:", self.data)
except Exception as e:
t, mes, tb = sys.exc_info()
print(traceback.format_exception(t, mes, tb)) # just print error for keep it execute server.;
def handleClose(self):
print("connection: closed " + self.address)
self.sendMessage("server exit")
#sys.exit()
def handleConnected(self):
print("Connected", self.address)
def start_data_receiver():
#udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#udp_sock.setblocking(False)
#udp_sock.bind(("127.0.0.1", 6666))
SSL = True
if SSL:
server = SimpleSSLWebSocketServer("localhost", 4246, DataWebSocket, "../certs/localhost.crt", "../certs/localhost.key.pem")
else:
server = SimpleWebSocketServer("localhost", 4246, DataWebSocket)
print("start server: 127.0.0.1:4246")
server.serveforever()
if __name__ == "__main__":
start_data_receiver()
这是错误打印:
['Traceback (most recent call last):\n', ' File "data_receiver_ws2.py", line 26, in __new__\n super().__new__(cls, cls_name, cls_bases, cls_dict)\n', 'TypeError: object() takes no parameters\n']
Traceback (most recent call last):
File "data_receiver_ws2.py", line 82, in <module>
start_data_receiver()
File "data_receiver_ws2.py", line 79, in start_data_receiver
server.serveforever()
File "/home/username/.local/lib/python3.6/site-packages/SimpleWebSocketServer/SimpleWebSocketServer.py", line 704, in serveforever
super(SimpleSSLWebSocketServer, self).serveforever()
File "/home/username/.local/lib/python3.6/site-packages/SimpleWebSocketServer/SimpleWebSocketServer.py", line 678, in serveforever
self.serveonce()
File "/home/username/.local/lib/python3.6/site-packages/SimpleWebSocketServer/SimpleWebSocketServer.py", line 614, in serveonce
if client.sendq:
AttributeError: type object 'DataWebSocket' has no attribute 'sendq'
答案 0 :(得分:2)
__new__
需要创建cls
的实例并返回它。您将自己返回cls
。像这样:
def __new__(cls, cls_name, cls_bases, cls_dict):
instance = super().__new__(cls, cls_name, cls_bases, cls_dict)
instance.udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # add udp socket as a class attribute (not instance attribute)
instance.udp_sock.setblocking(False)
instance.udp_sock.bind(("127.0.0.1", 6666))
return instance
获得AttributeError
的原因是,您然后尝试使用DataWebSocket
类型本身(从构造函数返回)而不是其实例,因此该属性将具有__init__
中设置的值不存在。
您的__init__()
方法没有什么大不了(除非您应该抑制异常:只需让异常冒泡到顶层即可)。 __init__
初始化传递给它的对象,它不返回任何内容。只需按您的方式调用超类__init__
。
__new__
构造一个新对象,因此它必须返回它。如果返回的对象是cls
的实例,则Python将自动调用__init__
。如果您返回不同的内容(如此处所做的操作),那么Python不会为您调用__init__
,因为类的__init__
只能用该类(或子类)的实例来调用。 / p>
答案 1 :(得分:0)
这是添加类属性的方式
class DataWebSocket(WebSocket):
my_attr = "banana"
您的类中的每个方法在技术上都与属性相同。