首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在socket Python中发送腌制类对象

在socket Python中发送腌制类对象
EN

Stack Overflow用户
提问于 2022-03-22 06:09:31
回答 1查看 86关注 0票数 0

我试图从客户端向服务器端发送一个类对象。我尝试过对类进行分类,并通过套接字发送被腌制的字节,但是值并没有传递到服务器端。

客户端utils.py

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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)。需要一些帮助来指出我犯的错误。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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

所以在你的例子中,如果真的这么简单的话,就像:

代码语言:javascript
运行
复制
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

能行的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71567592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档