你如何设置全局Abort处理程序?

rco*_*yer 5 wolfram-mathematica

在回答这个问题时,我建议 OP在他的笔记本开头打开一个流,并在结束时关闭它.但是,如果Abort生成了一个,则流将保持打开状态,如果他们尝试再次打开它而不先检查,则会造成严重破坏.如果仅对单个功能需要流,则解决方案将很简单,但整个笔记本都需要它.显然,可以添加一个检查来查看流是否已经打开,但有没有办法绑定到全局Abort处理程序,以便可以全局处理这类问题?

编辑:具体来说,我正在寻找一种方法来运行任意代码,Abort无论代码当前是否在其中运行CheckAbort.基本上,Abort如果可能的话,我想设置一个全局处理程序.如果这在笔记本级别存在,那就更好了.

abc*_*bcd 8

一种非常简单的方法是在文件开头发出以下内容:

Close /@ Streams[] // Quiet
Run Code Online (Sandbox Code Playgroud)

标准流stdout并且stderr无法关闭,您可以使用静音警告Quiet.但是,这也假设您没有任何您关心的开放流.

要处理Abort和关闭流,您可以修改$Post如下:

$Post := If[# === $Aborted, Close[strm], #] &
Run Code Online (Sandbox Code Playgroud)

strm您打开的流在哪里.


Leo*_*rin 8

作为替代方案,如果您想将效果本地化为单个笔记本,您可以按照以下方式执行操作:

SetOptions[EvaluationNotebook[], 
   CellEvaluationFunction -> 
     (ToExpression[#, StandardForm,
         Function[
            Null,
            Module[{aborted = $Aborted},
              Internal`WithLocalSettings[
                 Null,
                 aborted = (ReleaseHold[Most[Hold[##]]];Last[Hold[##]]),
                 AbortProtect[
                   If[aborted === $Aborted,
                      Print["Did cleanup"]; Abort[]
                   ]]]], 
            HoldAll]] &)
]
Run Code Online (Sandbox Code Playgroud)

注意:重写以包含@Alexey的建议

注2:修改为在单个单元中容纳多个输入.在这种情况下,除了最后一个输出都被抑制

Print["Did cleanup"]用任何清理代码替换代码的地方.

  • 我认为值得包装`Print ["Did cleanup"]; 在AbortProtect中中止[]`.另外,`CheckAbort`不允许捕获中断.以这种方式使用``Internal`WithLocalSettings``而不是`CheckAbort`是合理的. (2认同)