我有通过网络套接字相互通信的服务器和客户端程序。
我想要的是通过套接字发送从 scandir.scandir()
获得的目录条目 (scandir.DirEntry
)。
目前我正在使用 pickle
和 cPickle
模块,并提出了以下内容(仅摘录):
import scandir, pickle
s = scandir.scandir("D:\\PYTHON")
entry = s.next()
data = pickle.dumps(entry)
但是,我收到以下错误堆栈:
File "untitled.py", line 5, in <module>
data = pickle.dumps(item)
File "C:\Python27\Lib\pickle.py", line 1374, in dumps
Pickler(file, protocol).dump(obj)
File "C:\Python27\Lib\pickle.py", line 224, in dump
self.save(obj)
File "C:\Python27\Lib\pickle.py", line 306, in save
rv = reduce(self.proto)
File "C:\Python27\Lib\copy_reg.py", line 70, in _reduce_ex
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle DirEntry objects
我怎样才能摆脱这个错误?
我听说过使用 marshall
或 JSON
。更新:JSON
没有转储对象中的所有数据。
是否有任何完全不同的方法可以通过套接字发送对象?
在此先感谢您的帮助。
是的,os.DirEntry
对象旨在短暂存在,而不是真正保留或序列化。如果您需要对其中的数据进行序列化,看起来您已经在自己的答案中解决了这个问题——序列化(腌制)您需要的属性的字典版本。
要反序列化为像 os.DirEntry
实例一样走路和嘎嘎叫的对象,请创建一个模仿您需要的东西的 PseudoDirEntry
类。
请注意,您可以直接序列化 stat 对象,这样就省去了从中挑选字段的时间。
结合起来,看起来像这样:
class PseudoDirEntry:
def __init__(self, name, path, is_dir, stat):
self.name = name
self.path = path
self._is_dir = is_dir
self._stat = stat
def is_dir(self):
return self._is_dir
def stat(self):
return self._stat
然后:
>>> import os, pickle
>>> entry = list(os.scandir())[0]
>>> pickled = pickle.dumps({'name': entry.name, 'path': entry.path, 'is_dir': entry.is_dir(), 'stat': entry.stat()})
>>> loaded = pickle.loads(pickled)
>>> pseudo = PseudoDirEntry(loaded['name'], loaded['path'], loaded['is_dir'], loaded['stat'])
>>> pseudo.name
'.DS_Store'
>>> pseudo.is_dir()
False
>>> pseudo.stat()
os.stat_result(st_mode=33188, st_ino=8370294, st_dev=16777220, st_nlink=1, st_uid=502, st_gid=20, st_size=8196, st_atime=1478356967, st_mtime=1477601172, st_ctime=1477601172)
我是一名优秀的程序员,十分优秀!