我试图从客户端向服务器端发送一个类对象。我尝试过对类进行分类,并通过套接字发送被腌制的字节,但是值并没有传递到服务器端。
客户端utils.py
from collections import defaultdict
class Utils:
_filter_ip = []
_filter_vrf = defaultdict(list)
@classmethod
def filter_ip(cls):
return cls._filter_ip
@classmethod
def set_filter_ip(cls, ip_list):
cls._filter_ip = ip_list
@classmethod
def filter_vrf(cls):
return cls._filter_vrf
@classmethod
def set_filter_vrf(cls, device_name, vrf_list):
cls._filter_vrf[device_name] = vrf_list客户端client.py
import socket
import pickle
from utils import Utils
HOST = '127.0.0.1'
PORT = 5001
s = socket.socket()
s.connect((HOST, PORT))
Utils.set_filter_ip(['0.0.0.0/0', '10.0.0.0/8'])
Utils.set_filter_vrf('device1', ['vrf1', 'vrf2'])
pickled_data = pickle.dumps(Utils)
s.send(pickled_data)服务器端utils.py
from collections import defaultdict
class Utils:
_filter_ip = []
_filter_vrf = defaultdict(list)
@classmethod
def filter_ip(cls):
return cls._filter_ip
@classmethod
def set_filter_ip(cls, ip_list):
cls._filter_ip = ip_list
@classmethod
def filter_vrf(cls):
return cls._filter_vrf
@classmethod
def set_filter_vrf(cls, device_name, vrf_list):
cls._filter_vrf[device_name] = vrf_list服务器端server.py
import socket
import os
import json
import pickle
from utils import Utils
class Server:
_SERVER_HOST = '127.0.0.1'
_SERVER_PORT = 5001
_BUFFER_SIZE = 4096
_SEPARATOR = '<SEPERATOR>'
def __init__(self):
self._socket = socket.socket()
self._client = None
def init_socket(self):
self._socket.bind((self._SERVER_HOST, self._SERVER_PORT))
self._socket.listen(5)
def listen_socket(self):
self._client, address = self._socket.accept()
def recv_data(self):
data = self._client.recv(self._BUFFER_SIZE)
pickled_data = pickle.loads(data)
print(pickled_data.filter_ip())
def run_server(self):
self.init_socket()
self.listen_socket()
while True:
self.recv_data()recv_data方法从Utils类打印未被挑选的对象,但是Utils类中的数据丢失( filter_ip和filter_vrf)。需要一些帮助来指出我犯的错误。
发布于 2022-03-22 06:22:59
阅读这些文档是个好主意。在本节中,有人解释说:
请注意,函数(内置和用户定义的)是由“完全限定”的名称引用(而不是按值)选择的。[2] --这意味着只对函数名进行了腌制,并在其中定义了该模块的名称。函数的代码和它的任何函数属性都不会被腌制。因此,定义模块必须在解酸洗环境中被导入,并且模块必须包含命名对象,否则会引发异常。[3] 类似地,类是通过命名引用对其进行筛选的,因此在非泡沫化环境中也应用了相同的限制。
但是,在本节和如何允许对给定类进行自定义筛选的示例中,可以实现:
导入io导入泡菜类MyClass: my_attribute =1 class MyPickler(pickle.Pickler):def reducer_override(self,obj):“”自定义MyClass减速机“”。如果getattr(obj,"__name__",None) == "MyClass":返回类型(obj.__name__,obj.__bases__,{‘my_obj.__bases__’:obj.my_attribute})返回通常的还原返回NotImplemented f= io.BytesIO() p= MyPickler(f) p.dump( MyClass ) del MyClass unpickled_class = pickle.loads(f.getvalue()) assert (unpickled_class,type) Assertunpickled_class.__name__ == "MyClass“断言unpickled_class.my_attribute == 1
所以在你的例子中,如果真的这么简单的话,就像:
class MyPickler(pickle.Pickler):
def reducer_override(self, obj):
"""Custom reducer for Utils."""
if getattr(obj, "__name__", None) == "Utils":
return type, (obj.__name__, obj.__bases__, vars(obj))
else:
# For any other object, fallback to usual reduction
return NotImplemented能行的。
https://stackoverflow.com/questions/71567592
复制相似问题