我想创建一个描述文件资源的类,然后选择它。这部分很简单。具体来说,假设我有一个类“A”,它具有对文件进行操作的方法。如果它不包含文件句柄,我可以pickle这个对象。我希望能够创建文件句柄以访问“A”描述的资源。如果我在类“A”中有一个“open()”方法打开并存储文件句柄供以后使用,那么“A”不再是pickleable。 (我在这里添加打开文件包括一些不能缓存的非平凡索引 - 第三方代码 - 因此在需要时关闭和重新打开并非没有费用)。我可以将类“A”编码为可以为所描述的文件生成文件句柄的工厂,但这可能导致多个文件句柄同时访问文件内容。我可以使用另一个类“B”来处理类“A”中文件的打开,包括锁定等。我可能会过度思考这个,但任何提示都会受到赞赏。
答案 0 :(得分:6)
问题不太清楚;它看起来像是:
基本上,您希望将可打开的文件设为可选。你可以相当容易地做到这一点,但有一些警告。这是一个不完整但功能齐全的样本:
import pickle
class PicklableFile(object):
def __init__(self, fileobj):
self.fileobj = fileobj
def __getattr__(self, key):
return getattr(self.fileobj, key)
def __getstate__(self):
ret = self.__dict__.copy()
ret['_file_name'] = self.fileobj.name
ret['_file_mode'] = self.fileobj.mode
ret['_file_pos'] = self.fileobj.tell()
del ret['fileobj']
return ret
def __setstate__(self, dict):
self.fileobj = open(dict['_file_name'], dict['_file_mode'])
self.fileobj.seek(dict['_file_pos'])
del dict['_file_name']
del dict['_file_mode']
del dict['_file_pos']
self.__dict__.update(dict)
f = PicklableFile(open("/tmp/blah"))
print f.readline()
data = pickle.dumps(f)
f2 = pickle.loads(data)
print f2.read()
注意事项和注释,有些是明显的,有些则不那么:
open
获取的文件对象进行操作。如果您在文件上使用包装类,例如gzip.GzipFile
,则应该高于此值,而不是低于此值。从逻辑上讲,将其视为file
上的装饰者类。file
类。即使你现在只使用Python 2,也不要继承file
。我不会这样做;腌制数据取决于外部文件不变化和停留在同一个地方是脆弱的。这使得甚至难以重新定位文件,因为你的腌制数据没有意义。
答案 1 :(得分:1)
如果你打开一个指向文件的指针,腌制它,然后再尝试重新构建,则无法保证文件仍可用于打开。
详细说明,文件指针实际上代表了与文件的连接。就像数据库连接一样,你不能“腌制”连接的另一端,所以这不起作用。
是否可以在自己的进程中将文件指针保留在内存中?
答案 2 :(得分:1)
听起来你知道你不能腌制手柄,而你没关系,你只想腌制可以腌制的部分。正如你的对象现在所说,它不能被腌制,因为它有手柄。我有这个权利吗?如果是这样,请继续阅读。
对于这些情况,pickle模块将让你的类描述自己的pickle状态。您想要定义自己的__getstate__
方法。 pickler将调用它来获取要被pickle的状态,只有当方法丢失时才会继续并且做默认的尝试pickle所有属性。