我在datalore.jetbrains.com中使用datalore内核。在我的笔记本中有3个单元格(这是一个我能够重现此错误的最小工作示例):
#%%
class MyClass:
def __getattribute__(self, name):
return 123
#%%
aaa = MyClass()
#%%
aaa当我尝试执行第三个单元格时,我得到了一个错误,Can't use object "aaa" outside of the cell where it's defined。该消息清楚地表明,变量aaa只能在第二个单元格中使用。但是为什么datalore内核有这样的限制呢?
发布于 2020-12-11 17:36:48
简短的答案是,Datalore内核在执行单元后将运行时环境保存在磁盘上。
为什么datalore内核需要这样做?下面是一个长长的答案。为了理解问题的根本原因,我们需要知道datalore内核是如何执行单元的。
如果我们忘记所有关于Jupyter内核的知识,就更容易掌握它。Datalore内核与Jupyter内核有很大的不同,因为它是可复制的和增量。
可重复性
您是否曾经遇到过这样的情况:您需要从头开始重新运行notebook中的所有单元,因为您忘记了单元的执行顺序?你有没有和别人一起分享过笔记本和描述单元格执行顺序的笔记?有了datalore内核,你就不需要做这样的事情了。它确保始终以完全相同的顺序计算单元格,即按照它们在notebook中定义的顺序。每当执行第N个单元格时,datalore内核都会自动计算前面的所有单元格。您可能认为它一定非常慢,但事实并非如此。这就引出了内核的第二个关键属性。
增量思维
Datalore内核将每个单元执行的结果保存在磁盘上。结果是一个简单的运行时环境。实际上,它只是一个对象及其名称的字典。这就是为什么datalore内核不需要重新计算未更改的单元,因为结果是已知的-它持久保存在磁盘上。因此,在典型的实际情况下,当您使用一个单元格并不时地运行此单元格时-以前的单元格不会重新计算(仅在第一次)。此属性自然会施加以下限制:如果要在多个单元格中使用对象,则需要使其可序列化。在相反的情况下,您只能在一个单元格中使用一个对象。
附注:在此特定示例中,该问题是由__getattribute__方法的错误实现引起的。这样的实现意味着getattr(aaa, attr_name, None)的每次调用都返回123,这显然不是在所有情况下都能很好地工作。这就是为什么在尝试序列化对象aaa时出现一些错误的原因,因此它没有保存在磁盘上。
https://stackoverflow.com/questions/65248865
复制相似问题