我正在嘗試將自定義 Python 物件從客戶端發送到服務器,但額外的挑戰是在服務器中沒有對物件類的參考。如果您在服務器腳本中有類宣告,那么它會正確地重構 Python 物件。否則,它只是無法重建。
我嘗試使用pickle并jsonpickle發送 Python 物件(您可以通過OPTION變數選擇這兩個選項)。注釋掉類宣告后,這兩種方法都不起作用。
服務器
from socket import socket, gethostbyname, AF_INET, SOCK_DGRAM
import pickle
import jsonpickle
OPTION = 'pickle'
PORT_NUMBER = 5000
SIZE = 4000
# Required (but I don't want this!)
# class A:
# ...
s = socket(AF_INET, SOCK_DGRAM)
s.bind((gethostbyname('0.0.0.0'), PORT_NUMBER))
(data,addr) = s.recvfrom(SIZE)
print(data)
if OPTION == 'pickle':
output = pickle.loads(data)
print(output)
elif OPTION == 'jsonpickle':
output = jsonpickle.decode(data)
print(output)
客戶
import sys
from socket import socket, AF_INET, SOCK_DGRAM
import pickle
import jsonpickle
OPTION = 'pickle'
SERVER_IP = '127.0.0.1'
PORT_NUMBER = 5000
class A:
...
a = A()
s = socket(AF_INET, SOCK_DGRAM)
s.connect((SERVER_IP, PORT_NUMBER))
if OPTION == 'pickle':
s.send(pickle.dumps(a))
elif OPTION == 'jsonpickle':
s.send(jsonpickle.encode(a).encode())
輸出
這些是類A在服務器中時的輸出:
$ python server.py # jsonpickle
b'{"py/object": "__main__.A"}'
<__main__.A object at 0x7f4557a675e0>
$ python server.py # pickle
b'\x80\x04\x95\x15\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x01A\x94\x93\x94)\x81\x94.'
<__main__.A object at 0x7fcab9fc9bb0>
這些是類A不是服務器的一部分時的輸出:
$ python server.py # pickle
b'\x80\x04\x95\x15\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x01A\x94\x93\x94)\x81\x94.'
Traceback (most recent call last):
File "/home/eduardo/Downloads/SO_Question/server.py", line 21, in <module>
output = pickle.loads(data)
AttributeError: Can't get attribute 'A' on <module '__main__' from '/home/eduardo/Downloads/SO_Questi
on/server.py'>
$ python server.py # jsonpickle
b'{"py/object": "__main__.A"}'
{'py/object': '__main__.A'}
我研究了其他方法,例如Pyro,但我不太確定這些方法是否適用于我的用例。也許還有其他工具可以在這里提供幫助。這個服務器-客戶端示例只是我正在處理的一個更大專案的一個玩具問題:ChimeraPy。目標是讓服務器向客戶端分發自定義和唯一的代碼。通過使用客戶端的計算資源來執行自定義代碼,使用像 Pyro 這樣的代理并不理想,因為它們不像集群那樣分配計算負載。
任何幫助將不勝感激。謝謝!
試過:
- 看了以下 SO 問題:如何通過 python 中的套接字發送類,如何通過網路發送物件,如何通過 python 中的套接字發送類?,以及如何通過python發送物件?.
- 測驗發送一個類,
jsonpickle但它沒有幫助重建 - 深入研究
jsonpickle檔案,但無法確定任何可以規避問題的方法
希望:
- 在套接字的另一側找到發送自定義 Python 物件而不參考的解決方案
uj5u.com熱心網友回復:
使用@metatoaster 推薦的鏈接1和2,我能夠實作所需的行為:
服務器
from socket import socket, gethostbyname, AF_INET, SOCK_DGRAM
import pickle
import dill
import jsonpickle
OPTION = 'dill'
PORT_NUMBER = 5000
SIZE = 4000
# Required (but I don't want this!)
# class A:
# ...
s = socket(AF_INET, SOCK_DGRAM)
s.bind((gethostbyname('0.0.0.0'), PORT_NUMBER))
(data,addr) = s.recvfrom(SIZE)
print(data)
if OPTION == 'pickle':
output = pickle.loads(data)
print(output)
elif OPTION == 'jsonpickle':
output = jsonpickle.decode(data)
print(output)
elif OPTION == 'dill':
output = dill.loads(data)
print(output)
print(output.multiple(3))
客戶
import sys
from socket import socket, AF_INET, SOCK_DGRAM
import pickle
import jsonpickle
import dill
OPTION = 'dill'
SERVER_IP = '127.0.0.1'
PORT_NUMBER = 5000
class A:
def __init__(self):
self.num = 2
def multiple(self, n):
return self.num * n
a = A()
s = socket(AF_INET, SOCK_DGRAM)
s.connect((SERVER_IP, PORT_NUMBER))
if OPTION == 'pickle':
s.send(pickle.dumps(a))
elif OPTION == 'jsonpickle':
s.send(jsonpickle.encode(a).encode())
elif OPTION == 'dill':
s.send(dill.dumps(a))
運行server.pyand后client.py,我得到以下輸出:
$ python server.py
b'\x80\x04\x95\x17\x02\x00\x00\x00\x00\x00\x00\x8c\ndill._dill\x94\x8c\x0c_create_type\x94\x93\x94(h\
x00\x8c\n_load_type\x94\x93\x94\x8c\x04type\x94\x85\x94R\x94\x8c\x01A\x94h\x04\x8c\x06object\x94\x85\
x94R\x94\x85\x94}\x94(\x8c\n__module__\x94\x8c\x08__main__\x94\x8c\x08__init__\x94h\x00\x8c\x10_creat
e_function\x94\x93\x94(h\x00\x8c\x0c_create_code\x94\x93\x94(K\x01K\x00K\x00K\x01K\x02KCC\nd\x01|\x00
_\x00d\x00S\x00\x94NK\x02\x86\x94\x8c\x03num\x94\x85\x94\x8c\x04self\x94\x85\x94\x8c-/home/eduardo/Do
wnloads/SO_Question/client.py\x94h\x10K\rC\x02\x00\x01\x94))t\x94R\x94c__builtin__\n__main__\nh\x10NN
t\x94R\x94}\x94}\x94(\x8c\x0f__annotations__\x94}\x94\x8c\x0c__qualname__\x94\x8c\nA.__init__\x94u\x8
6\x94b\x8c\x08multiple\x94h\x12(h\x14(K\x02K\x00K\x00K\x02K\x02KCC\n|\x00j\x00|\x01\x14\x00S\x00\x94N
\x85\x94h\x18h\x19\x8c\x01n\x94\x86\x94h\x1bh(K\x10C\x02\x00\x01\x94))t\x94R\x94c__builtin__\n__main_
_\nh(NNt\x94R\x94}\x94}\x94(h#}\x94h%\x8c\nA.multiple\x94u\x86\x94b\x8c\x07__doc__\x94N\x8c\r__slotna
mes__\x94]\x94ut\x94R\x94)\x81\x94}\x94h\x17K\x02sb.'
<__main__.A object at 0x7fe8ec0656d0>
6
成功!謝謝您的幫助!
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/524256.html
