在回答这个question时,我suggested OP在他的笔记本开头打开一个流并在结束时关闭它。但是,如果生成Abort
,则流将保持打开状态,如果他们尝试再次打开它而不先检查,则会造成严重破坏。如果仅对单个函数需要流,solution将是直截了当的,但整个笔记本需要它。显然,可以添加一个检查来查看流是否已经打开,但有没有办法绑定到全局Abort
处理程序,以便可以全局处理这类问题?
编辑:具体来说,我正在寻找一种在Abort
出现时运行任意代码的方法,无论代码当前是否在{{3}内运行}}。基本上,如果可能的话,我想设置一个全局Abort
处理程序。如果这在笔记本级别存在,那就更好了。
答案 0 :(得分:8)
一种非常简单的方法是在文件开头发出以下内容:
Close /@ Streams[] // Quiet
无法关闭标准流stdout
和stderr
,您可以使用Quiet
使警告静音。但是,这也假设您没有任何您关心的开放流。
要处理Abort
并关闭流,您可以修改$Post
,如:
$Post := If[# === $Aborted, Close[strm], #] &
其中strm
是您打开的流。
答案 1 :(得分: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]] &)
]
注意:重写以包含@Alexey
的建议注2:修改后可容纳单个单元格中的多个输入。在这种情况下,除了最后一个输出之外的所有输出都被抑制
使用您拥有的任何清理代码替换Print["Did cleanup"]
代码。