我用一个简单的打印命令转储了多个 defaultdict,如下所示:
defaultdict(<type 'list'>, {'actual': [20000.0, 19484.0, 19420.0], 'gold': [20000.0, 19484.0, 19464.0]})
是否有一些标准解析器可以用来检索它们?我知道我应该使用 pickle,但是生成这些 defaultdict 的代码非常慢,我想避免重新运行它。
我用一个简单的打印命令转储了多个 defaultdict,如下所示:
defaultdict(<type 'list'>, {'actual': [20000.0, 19484.0, 19420.0], 'gold': [20000.0, 19484.0, 19464.0]})
是否有一些标准解析器可以用来检索它们?我知道我应该使用 pickle,但是生成这些 defaultdict 的代码非常慢,我想避免重新运行它。
如果您的 defaultdict 的类型是 always <type 'list'>
,您可以使用以下内容:
from collections import defaultdict
s = """
defaultdict(<type 'list'>, {'actual': [20000.0, 19484.0, 19420.0], 'gold': [20000.0, 19484.0, 19464.0]})
"""
data = eval(s.replace("<type 'list'>", 'list'))
人们会告诉你这eval()
是不安全和邪恶的,但如果有人试图将有害代码注入你转储的数据中,他们可能同样容易编辑你的源代码。如果您从中获取此数据的文本文件比您的源代码更易于访问,那么您可能不想使用此方法。
如果您的 defaultdicts 有多种类型,但它们都是内置类型(或易于repr
在类型名称之间转换),那么您仍然可以使用此方法进行多次替换,例如:
for rep, typ in ((repr(list), 'list'), (repr(dict), 'dict')):
s = s.replace(rep, typ)
data = eval(s)
完全丑陋,但有效:
s = """
defaultdict(<type 'list'>, {'actual': [20000.0, 19484.0, 19420.0], 'gold': [20000.0, 19484.0, 19464.0]})
"""
import re, ast
s = re.sub('^[^{]+', '', s)
s = re.sub('[^}]+$', '', s)
print ast.literal_eval(s)
请注意,这会创建一个普通的dict
,而不是一个 defaultdict。
您可以创建自己的子类:
from collections import defaultdict
class mydefdict(defaultdict):
def __repr__(self):
return "mydefdict(%s, %s)" % (repr(self.default_factory()) + ".__class__", repr(dict(self)))
然后像其他类型一样使用它eval
:
>>> d = mydefdict(list)
>>> d['foo'] = [1,2,3]
>>> d['bar']
[]
>>> print d
mydefdict([].__class__, {'foo': [1, 2, 3], 'bar': []})
>>> reprstring = repr(d)
>>> d2 = eval(reprstring)
>>> d2
mydefdict([].__class__, {'foo': [1, 2, 3], 'bar': []})
请注意,使用这种方式,将为结构中的每个对象引用创建一个单独的副本,即使其中一些引用是对同一对象的引用。