慕碼人2483693
2021-11-16 15:11:10
使用 jupyter lab/notebook 時,大多數(shù)情況下,我將這兩行放在筆記本的第一個單元格中:%reload_ext autoreload%autoreload 2這些通常允許我修改我導(dǎo)入的腳本并使用它們,而無需重新導(dǎo)入它們或重新啟動內(nèi)核。昨天遇到一個問題:我修改了腳本,在筆記本上執(zhí)行一個單元格報錯。重新啟動內(nèi)核并重做導(dǎo)入修復(fù)了它。我調(diào)查了這個問題,并試圖創(chuàng)建一個最小的例子。假設(shè)您有以下工作目錄:+-- nb.ipynb+-- scripts| +-- __init__.py| +-- script1.py筆記本由三個單元格組成:%reload_ext autoreload%autoreload 2\from scripts.script1 import Foo\a = Foo(42)在本實(shí)驗(yàn)開始時,script1 包含以下內(nèi)容:class Foo(): def __init__(self, x): self.x = x現(xiàn)在,我們執(zhí)行筆記本的 3 個單元格,一切正常。然后我們轉(zhuǎn)到 script1.py 并將其代碼替換為:class Bar(): def __init__(self, x): self.x = xclass Foo(Bar): def __init__(self, x): super().__init__(x)我們保存文件,返回筆記本,并執(zhí)行包含的單元格a = Foo(42) 這給出了以下錯誤:[autoreload of script.script failed: Traceback (most recent call last): File "/home/user/miniconda3/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 245, in check superreload(m, reload, self.old_objects) File "/home/user/miniconda3/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 384, in superreload update_generic(old_obj, new_obj) File "/home/user/miniconda3/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 323, in update_generic update(a, b) File "/home/user/miniconda3/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 288, in update_class if update_generic(old_obj, new_obj): continue File "/home/user/miniconda3/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 323, in update_generic update(a, b) File "/home/user/miniconda3/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 266, in update_function setattr(old, name, getattr(new, name))ValueError: __init__() requires a code object with 0 free vars, not 1]重新啟動內(nèi)核或再次執(zhí)行導(dǎo)入行可解決此問題。為什么autoreload在這種情況下不起作用?PS:這是在python 3.6中完成的,我最初的問題是在python 3.7中
2 回答

慕俠2389804
TA貢獻(xiàn)1719條經(jīng)驗(yàn) 獲得超6個贊
一、關(guān)于問題
為什么在這種情況下 autoreload 不起作用?
正如錯誤日志所述:
setattr(old, name, getattr(new, name)) ValueError: __init__() requires a code object with 0 free vars, not 1
autoreload
在這里做什么:
它嘗試__init__()
用新__init__()
函數(shù)代碼對象替換舊函數(shù)(代碼更改之前的函數(shù))的代碼對象。當(dāng)我檢查__init__()
代碼更改前后函數(shù)的空閑變量時,得到如下結(jié)果:
檢查代碼:
Foo.__init__.__code__.co_freevars
結(jié)果:
在代碼更改之前:()
,沒有自由變量。
代碼更改后:('__class__',)
,這里有一個空閑變量。這就是錯誤發(fā)生的原因。它不能用新的目標(biāo)代碼替換舊的目標(biāo)代碼。
2.如何解決問題
在這種情況下,因?yàn)?code>autoreload仍然是舊的函數(shù)對象,所以我們不能做任何事情,只能重新啟動內(nèi)核。
希望這有幫助。

POPMUISE
TA貢獻(xiàn)1765條經(jīng)驗(yàn) 獲得超5個贊
以下對我有用:
from importlib import reload reload(my_module)
不知道這是否適用于所有情況,但比重新啟動內(nèi)核容易得多。
添加回答
舉報
0/150
提交
取消