是否可以在不评估内容的情况下导入MX文件?

Sza*_*lcs 7 wolfram-mathematica

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


让我说明一下:

让我们创建一个变量data:

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

Out[2]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Run Code Online (Sandbox Code Playgroud)

它可以导出到MX并从MX导入,而无需进行任何定义:

In[3]:= ImportString@ExportString[data, "MX"]

Out[3]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Run Code Online (Sandbox Code Playgroud)

但是如果我们使用DumpSave呢?

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

Out[4]= {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}
Run Code Online (Sandbox Code Playgroud)

(并清楚data)

In[5]:= Clear[data]
Run Code Online (Sandbox Code Playgroud)

重新导入时,不返回任何内容:

In[6]:= Import["data.mx", {"MX", "HeldExpression"}]
Run Code Online (Sandbox Code Playgroud)

但是变量data再次定义,好像我们已经使用过一样Get.

In[7]:= data

Out[7]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Run Code Online (Sandbox Code Playgroud)

我希望得到类似的东西Hold[data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}],即类似于.m使用时写入文件的东西Save.


也许技术上不可能避免定义因为DumpSaveGet直接操作内核状态而不是编写和读取可评估的定义Save?这只是猜测.


(编辑)请注意:我不是试图以可以导入的方式保存"已保留".我已经可以使用了Export.我想要导入以前的DumpSaved MX文件.


回答看起来除非将MX文件保存为专门允许,否则无法执行此操作.

Leo*_*rin 7

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

所以,我在这里看不到真正的问题,因为你总是可以查询符号DownValues和其他...Values符号,并以未评估的形式提取规则的rhsides(有一些病态案例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];
Run Code Online (Sandbox Code Playgroud)

例如:

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]={}}]
Run Code Online (Sandbox Code Playgroud)

现在,主要功能:

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]
]
Run Code Online (Sandbox Code Playgroud)

您基本上将单个符号指定为其他符号的未评估定义的存储.以下是如何使用它:

dumpSave["data.mx", storage, data, dumpSave, dress]
Run Code Online (Sandbox Code Playgroud)

如果你现在清除storage符号和负载还原的文件,你会看到,其他保存符号的所有定义都存储在未计算形式DownValuesstorage.您只需要调用ReleaseHold它们来实际执行分配,但您也可以以未评估的形式访问它们.