我尝试在模块中定义一个函数,然后使用DumpSave
将函数定义保存到文件中。但是,重新加载函数失败。这是一个最小的例子
buildf[]:= Module[{res},
res[x_]:=x^2;
res
];
f=buildf[];
DumpSave["f.mx", f];
Clear[f];
Get["f.mx"]
现在我希望f
成为平方函数,但在Clear
语句之后它仍未定义。我该如何解决这个问题?
问题与几个月前的my earlier question密切相关,但那里的解决方案对我没有帮助。
任何暗示都赞赏!
更新
buildf
正在读取多个数据文件,对其进行转换,根据它们定义规则并调用Dispatch以快速查找。 buildf
返回的函数就像是数据的API。我想避免调用buildf
而是加载已创建数据函数的二进制转储。
Save
方法似乎很有希望,但它仍然不起作用。我将尝试隔离问题,以便我可以在这里重现它。
最终更新 在@Leonid的注释之后,会话中不保证局部变量的唯一性,我决定仅将此“DumpSave缓存机制”用于普通数据结构,而不是依赖于其他符号的函数。
答案 0 :(得分:3)
您正在从res
返回本地变量(Module
)。当然这不起作用,你最终得到res
的“本地化”(重命名)版本。
尝试
f = buildf[]
?f
你会得到像f=res$538
这样的东西。此局部变量具有属性Temporary
,可以随时删除(因此f
可以停止工作)。
如果您DumpSave
符号f
,其定义为f=res$538
将被保存,并且可以重新加载(您可以使用?f
进行验证)。但这不是很有用。
这里的问题是:你为什么要使用这个buildf
功能呢?你想要实现什么目标?
编辑:正如Leonid在下面指出的那样,我上面写的内容并不完全正确:从DownValue
返回Module
的符号似乎没有删除,即使他们没有被引用。人们可能仍然想知道这种行为在版本之间是否一致,将来会是一样的。
答案 1 :(得分:3)
如果您使用Save
代替DumpSave
,则可以看到正在发生的事情。
我得到一个看起来像这样的文件:
f = res$636
Attributes[res$636] = {Temporary}
res$636[x_] := x^2
这个(Save
而非DumpSave
)确实有效,但我建议Temporary
属性在使用{{DumpSave
属性时会导致丢失或首先保存。 1}}。
我必须拒绝上面的断言,因为我可以手动清除Temporary
符号中的res$*
属性,但仍然无法保存和加载。
答案 2 :(得分:2)
这显然比我初想的要基本得多。由于创建了依赖于系统的二进制格式,我自己很少使用DumpSave
,我认为它的行为与Save
非常相似。但是,情况似乎并非如此。
考虑:
test[x_] := x^2
f = test;
DumpSave["test.mx", f]
Quit[]
其次是:
Get["test.mx"]
Information[f]
Information[test]
在我的系统上,没有保存和/或加载test
的定义。
对比:
test2[x_] := x^2
f2 = test2;
Save["test2.m", f2]
Quit[]
其次是:
Get["test2.m"]
Information[f2]
Information[test2]
正确保存并加载test2
的定义。