如何将命名元组字典或命名元组发送到客户端(套接字)?
简单来说,我在服务器上有一个字典(dictData[name]=namedTuple
),里面存放着一些命名元组(记录)。
我的目标是通过 SOCKET 连接把整个字典(dictData
)或者其中的某个实例(dictData[key]
)发送给客户端,这样客户端就可以把它打印出来(显示在屏幕上)。
为了发送单个记录,我尝试了以下方法:
response = dictData["John"]
print (response) #ensure it is the correct record
s.send(response)
但是这产生了以下错误:
"TypeError: 'record' does not support the buffer interface"
我尝试过对它进行编码和转换,但无论我怎么做似乎都不行。我甚至考虑把它转换成字符串发送,但我也不知道怎么把命名元组转换成字符串。
而且,我也不知道从哪里开始才能把整个字典发送给客户端,这样他们就可以打印出所有的内容?
任何帮助都会非常感谢。
1 个回答
3
套接字(Sockets)只能发送和接收字节,所以你需要把命名元组(named tuples)和字典(dictionary)转换成其他格式。
你可以使用 JSON 来生成元组和字典的字符串表示。例如,json
库在编码时会生成一个(Unicode)字符串,你需要把这个字符串编码成 UTF-8(或类似格式)来得到字节:
import json
# sending one tuple
response = json.dumps(dictData["John"])
s.send(response.encode('utf8'))
# sending all of the dictionary
response = json.dumps(dictData)
s.send(response.encode('utf8'))
不过,这样做会丢失命名元组的属性名称;传输的值会变成一个 JSON 数组(也就是一个有序列表)。
另一个选择是使用pickle
模块;不过这样的话,接收方也必须用 Python 编写,并且要能从完全相同的位置导入相同的record
命名元组类型。
当 Pickle 加载数据时,会包含命名元组类型的完整名称,你必须在套接字的两端都能导入这个类型。如果你在模块的全局级别有一行代码:
record = namedtuple('record', 'field1 field2 field3')
那么from yourmodule import record
是可以的,但在另一端也必须使用完全相同的导入。
pickle.dumps()
会生成一个bytes
对象,可以直接写入套接字,而不需要编码。