我正在嘗試將一個類物件從客戶端發送到服務器端。我試圖腌制類并通過套接字發送腌制位元組,但該值沒有傳遞到服務器端。
客戶端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)。需要一些幫助來指出我犯的錯誤。
uj5u.com熱心網友回復:
閱讀檔案是個好主意。在本節中,說明:
請注意,函式(內置的和用戶定義的)是通過“完全限定”名稱參考而不是值來腌制的。[2]這意味著只有函式名和定義函式的模塊名稱被腌制。函式的代碼和它的任何函式屬性都沒有被腌制。因此,定義模塊必須在 unpickling 環境中是可匯入的,并且模塊必須包含命名物件,否則將引發例外。[3]
類似地,類是通過命名參考來腌制的,因此在 unpickling 環境中適用相同的限制。
但是,在本節和示例中,可以實作如何允許對給定類進行自定義酸洗:
import io import pickle class MyClass: my_attribute = 1 class MyPickler(pickle.Pickler): def reducer_override(self, obj): """Custom reducer for MyClass.""" if getattr(obj, "__name__", None) == "MyClass": return type, (obj.__name__, obj.__bases__, {'my_attribute': obj.my_attribute}) else: # For any other object, fallback to usual reduction return NotImplemented f = io.BytesIO() p = MyPickler(f) p.dump(MyClass) del MyClass unpickled_class = pickle.loads(f.getvalue()) assert isinstance(unpickled_class, type) assert unpickled_class.__name__ == "MyClass" assert 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
could work.
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/447836.html
