2012-01-04 47 views
7

问题:是否可以在不评估内容的情况下导入使用DumpSave保存的MX文件?是否可以在不评估内容的情况下导入MX文件?


让我说明:

让我们创建一个变量,data

In[2]:= data = Range[10] 

Out[2]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 

它可以出口到从MX进口未做任何定义:

In[3]:= [email protected][data, "MX"] 

Out[3]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 

但是如果我们使用DumpSave

In[4]:= DumpSave["data.mx", data] 

Out[4]= {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}} 

(和明确data

In[5]:= Clear[data] 

在重新导入,则返回什么:

In[6]:= Import["data.mx", {"MX", "HeldExpression"}] 

但变量data再次变为定义,因为如果我们使用Get

In[7]:= data 

Out[7]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 

我没有料想到会得到这样的Hold[data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}],即类似于将使用Save时被写入到一个.m文件的东西。


也许是技术上无法避免被作出的定义,因为DumpSaveGet直接操纵内核态的,而不是写作和阅读的定义可求像Save呢?这只是一个猜测。


(编辑)请注意:我不是在可导入“保持”的方式进行保存。我已经可以使用Export。我期待导入以前的DumpSave d MX文件。


回答看来这是不可能做到这一点,除非MX文件保存到的特别允许。

回答

7

我的理解是.mx文件的逻辑是相反的:加载.mx文件时,符号的定义(DownValues等)在最低级别创建,以便直接指定值到内部存储器位置,绕过主评估者。这就是为什么加载.mx文件如此之快的原因。看起来你不能同时拥有 - 你的期望对应于更高级别的符号代码。但是,您可以通过在某些上下文中使用符号来封装数据,作为该数据的句柄。

所以,我没有在这里看到一个真正的问题,因为你总是可以查询符号的DownValues和其他...Values并提取r.h.未规定形式的规则的两侧(有一些病理学案例,其中DownValues没有完全重建存储在其中的原始定义,但它们可以说是零度量,并且没有多少实际重要性)。您可以定义某个界面,这将允许您通过几个函数(符号)提取数据,而数据可以在封面下使用更多符号,这些符号会隐藏在这些符号的后面。

编辑

如果你控制了初次使用的DumpSave,这里是一个可能的说明 - 您可以创建自定义dumpSave样的功能。这些辅助函数编写关于符号的信息:

ClearAll[dress]; 
dress[prop_] := 
    Function[s, With[{pr = prop[s]}, Hold[prop[s] = pr]], HoldAll] 

ClearAll[getHeldProperties]; 
getHeldProperties[HoldComplete[s_Symbol]] := 
Thread[ 
    Through[(dress /@ { 
     DownValues, UpValues, OwnValues, 
     SubValues, DefaultValues, NValues, 
     FormatValues, Options, Messages, 
     Attributes 
     })[Unevaluated[s]]], 
    Hold]; 

例如:

In[284]:= 
getHeldProperties[HoldComplete[data]] 

Out[284]= Hold[{DownValues[data]={},UpValues[data]={},OwnValues[data]={HoldPattern[data]:> 
{1,2,3,4,5,6,7,8,9,10}},SubValues[data]={},DefaultValues[data]={}, 
NValues[data]={},FormatValues[data]={},Options[data]={},Messages[data]={}, 
Attributes[data]={}}] 

现在,主要的功能:

ClearAll[dumpSave]; 
SetAttributes[dumpSave, HoldRest]; 
dumpSave[file_String, storage_Symbol, symbs___] := 
    Module[{n = 1}, 
    Replace[ 
     Thread[HoldComplete[{symbs}]], 
     held : HoldComplete[s_] :> 
     (storage[n++] = getHeldProperties[held]), 
     {1}]; 
    DumpSave[file, storage] 
] 

基本上,你指定一个符号作为存储未评估的其他符号的定义。这里是你如何使用它:

dumpSave["data.mx", storage, data, dumpSave, dress] 

如果你现在清除storage符号和负载还原的文件,你会看到,其他保存符号的所有定义都存储在不计算形式的storageDownValues。您只需致电ReleaseHold即可执行分配,但您也可以以未评估的形式访问它们。

+0

@Szabolcs我添加了一些代码来说明问题的答案。 – 2012-01-04 19:20:25

2

首先,让我指出DumpSave似乎有一个无证的第三个参数。我发现这一点,而在他们的MX功能拖动功能。

通过评估?System`Private`BuildApplicationMXFunction(修复这些上下文标记 - SO标记可防止使用常规符号)来查看您自己。请注意,在函数的最后一行中,HoldAllComplete作为第三个参数给出。

不知道是否会被使用。无论如何,这是我认为你所要求的解决方案。

Remove[data, assignment]; 
assignment := (data = Range[10]) 

根据你的需要,你也可以尝试assignment := Defer[(data = Range[10])]

现在评价:

DumpSave["data.mx", assignment, HoldAllComplete] (*Also could try Unevaluated as 3rd arg *) 
Remove[data, assignment]; 
Import["data.mx", "HeldExpression"] 

并注意data是不确定的,直到评估assignment。如果使用Defer版本assignment,data将再次未定义并且分配将返回(字面上)data = Range[10]您可以使用[email protected]@assignment来评估并将原始分配恢复到data

现在是时候看狮子座的答案,看我怎么哑巴我!!):d

+0

如果你用双反引号(\'\')包含内联代码,那么你的驾驶室在其中包含一个反引号。看我的编辑到你的答案。 – Szabolcs 2012-01-05 08:07:38

+0

@Szabolcs谢谢。以为我曾尝试过。有时候,即时预览看起来很脆弱。另一个问题是内联代码之前和之后的空格。如果你放置一个空间(就像平常一样),它会显示为两个空格。不留空间,看起来应该如此。我大多数时候使用几种不同的浏览器,但Chrome。 – telefunkenvf14 2012-01-05 10:40:12

相关问题