介质 - 热代码重新加载Python

2021-04-10 03:29:56

介质更新Live代码巧妙:更改函数或方法将使代码指针剪辑,以便同时修改所有现有实例以实现新行为。修改模块时,只会重新运行更改的行。

使用介的最简单方法是将-M致致脚本调用,或使用介绍而不是Python。您可以使用-v来获取有关观看文件的反馈以及更改文件时会发生什么。

用法:介介[ - verbose] [ - vatch path] [-m module] [path] ...运行一个python脚本,以便它是实时可编辑的。定位参数:脚本的路径路径运行...脚本参数Optional Arguments:-h,--help显示此帮助消息和退出 - verbose,-v显示观看的文件和它们发生的更改--watch path,-w路径通配符路径/目录手表-M模块模块或模块:运行功能

首先,如果有问题,请使用详细的标志(介质-v)来获取更多信息。它将输出手表<文件>对其手表和更新/添加/删除且更新/删除且函数&gt的每个文件的陈述。在原始文件中更新,添加或删除函数时的语句,然后保存它。

默认情况下,在当前工作目录中观看脚本。尝试判决-w<文件>观看特定文件,或介绍-W /观看所有文件。

它&#39可能是因为您使用的编辑器保存到临时交换文件中,并将其移动到位(VI执行此处)。介质使用介绍时的看门狗库在发生时失去文件。挂断更好的解决方案,您可以尝试配置编辑器,以便直接写入文件。例如,在VI中,:SET NOMRITEBACKUP似乎执行诀窍(将其放在您的.vimrc中或在第一次保存之前执行它)。

如果您正在在' s当前正在运行的函数内编辑A for循环的主体,则下次调用函数时,更改将实际上实际上。解决方法是将for循环的主体解压缩到自己的辅助函数中,然后您可以编辑。或者,您可以使用沿译文重新加载。

类似地,更新生成器或异步函数不会更改已在运行的生成器或异步函数的行为。

在判决不理解的某些数据结构中装饰或藏起时,可能会更新某些功能。致辞确实必须找到他们更新它们,不幸的是。

您可以调用murigged.watch()以编程方式开始观看更改。这也应该在Ipython或Jupyter内工作,作为AutoReload Magic的替代品。

默认情况下,将关注当前目录中的所有文件,但您可以使用murigged.watch(" script.py")只能观看单个文件,或jurgged.watch(" /&# 34;)观看所有模块。

可以使用Recoder进行编程方式更改功能。用murigges.make_recoder制作一个。这可用于实现热修补或嘲笑。更改也可以写回文件系统。

从致介导导入make_recoder def f(x):return x * x断言f(2)== 4#更改函数的行为,但不在原始文件recoder = make_recoder(f)recoder中。补丁(" def f(x):返回x * x * x")断言f(2)== 8#revert更改Recoder。恢复()断言F(2)== 4#或:将修补程序写入原始文件本身Recoder。犯罪()

如果没有提交,则还原只会恢复到最后一个提交,或者原始内容。

Recoder还允许您将导入,辅助功能等添加到补丁,但必须在这种情况下使用recoder.patch_module(...)。

致辞工作在令人惊讶的大量情况下,但有几个案例赢得了几个案例,或者在' T工作,或者可能出现问题:

已运行的函数将继续使用现有代码运行。只有下一个调用将使用新代码。如果要能够修改循环运行,则可以使用重新加载除了介绍。

更改初始化器或属性名称可能会导致现有实例的错误。介质修改了类的所有现有实例,但它不会重新运行现有实例上的__init__或重命名属性,因此您可以轻松地使用损坏的对象(新方法,但旧数据)。

更新装饰器或封闭件的代码可能或可能无法工作。介质将尽力而为,但有可能会更新一些封闭物,而不是其他人。

查看/调整功能代码的装饰器可能不会正确更新。尝试编译/ JIT Python代码Won' t知道关于介绍和赢得的' t能够重做新代码的工作。

如果它们在旧功能上设置(介介特定)__conform__属性,则可以工作。 __conform__将引用应替换它的函数,或者如果要删除它。

通过模块爬行以查找功能对象并将其与定义匹配。它将通过课堂成员,遵循功能' __wrapped__和__clure__指针,等等。

修改文件时,将其重新解析为一组定义并将其与原始定义匹配,并产生一组更改,添加和删除。

有关更改,请执行新代码(如果他们没有更改,则剥离装饰器),然后采取生成的函数' s内部__code__指针并将其推入旧的函数。如果更改失败,则将重新解释为旧代码的删除,然后添加新代码。

介质的两个最可比的实现和#39; s功能集的两个功能集(但它可能有点难以找到相当的一切)是Ipython和Limeade中的%自动加载。以下是关键差异:

当其代码更改时,它们都重新执行整个模块。相比之下,手术提取来自解析树的更改函数,只取而代之。它仅在模块中执行新的或更改的语句。

哪个更好是有些情况依赖性:一方面,重新执行模块将拿起更多的变化。另一方面,它将重新初始化模块变量和状态,因此某些事情可能会破裂。介相' S方法更保守,只会拿起修改的功能,但它不会触及其他任何东西,所以我相信它不太可能产生意外的副作用。它也告诉你它在做什么:)

他们将重新执行装饰器,而介狗将挖掘它们并更新它在内部找到的功能。

再次,没有客观地卓越的方法。 %autOreload将正确重新执行更改的装饰器,但这些装饰器将返回新对象,因此如果模块导入已装饰的功能,则会赢得' t更新到新版本。 如果您只修改函数'但是,如果介绍,则介绍通常能够在装饰器内更改它,因此所有旧实例都将使用新的行为。 这是一个双刃剑,因为即使介狗也可以将Live更新添加到具有零线的额外代码的现有脚本,它根本不是线程(代码可以在更新的中间执行,这可能是不一致的 状态)。 重新加载可以包装迭代器以使循环可修改。 介质不能这样做,但您可以同时使用两个包。