提问人:user93353 提问时间:10/3/2023 最后编辑:Mark Rotteveeluser93353 更新时间:10/6/2023 访问量:44
更新导入后如何重新加载导入?Sage 似乎直到会话结束才重新加载它
How to reload an import after updating it? Sage doesn't seem to reload it till end of session
问:
我有一个名为的文件,其中包含一个类。
我有一个将其导入为MyClass.py
MyClass
MyPrg.sage
from MyClass import MyClass
然后实例化并调用一个方法。MyClass
我通过调用 .如果在程序退出后,我更改并再次运行,它似乎使用较旧的.让它运行更新的类的唯一方法是杀死 shell 并在新的 shell 中运行它。MyPrg.sage
load
MyClass.py
MyPrg.sage
load
MyClass.py
有没有办法告诉 Sage 重新加载更新的导入?
我在Windows 10上运行Sage 9.3。
答:
在 Python 中,importlib
模块可用于重新加载已导入的模块()。
但是,需要注意的是,重新加载模块并不总是那么简单,尤其是在处理对象定义时,因为现有对象不会自动更新以反映模块代码中的更改。importlib.reload(module)
在 SageMath 中,您需要:
- 将模块导入到文件中。
importlib
MyPrg.sage
- 作为模块导入。
MyClass
- 用于在更新时重新加载模块。
importlib.reload()
MyClass
MyClass.py
那是:
import importlib
import MyClass
# Load the module initially
my_class_instance = MyClass.MyClass()
# do something
# Now, assume MyClass.py has been updated, and you want to reload it:
importlib.reload(MyClass)
# Now when you create a new instance, it will reflect the updated code:
my_class_instance = MyClass.MyClass()
使用此设置,每次调用 时,Python 都会从 重新加载模块,以反映您对该文件所做的任何更改。importlib.reload(MyClass)
MyClass
MyClass.py
如前所述,任何现有的实例都不会更新;只有在重新加载模块后创建的新实例才会反映更新的代码。MyClass
下面是一个示例来说明这一点:
假设最初如下所示:MyClass.py
class MyClass:
def method(self):
print("Old Method")
您有一个导入和创建实例的脚本:MyPrg.sage
MyClass
from MyClass import MyClass
obj = MyClass()
obj.method() # Outputs: Old Method
现在,您更新以更改:MyClass.py
method
class MyClass:
def method(self):
print("New Method")
如果重新加载模块并调用现有实例,您仍将看到旧行为:MyClass
method
obj
import importlib
import MyClass
importlib.reload(MyClass)
obj.method() # Outputs: Old Method
但是,如果您创建一个新实例 ,您将看到新行为:MyClass
new_obj = MyClass.MyClass()
new_obj.method() # Outputs: New Method
这说明了现有对象如何保留其在重新加载模块之前的行为,而新对象则反映更新的类定义。
我想要的不是在做某事后重新加载。
我想在启动程序本身时重新加载。
- 我跑.
MyPrg
MyPrg
完成执行- 我更新.
MyClass
- 我重新运行,旧的似乎仍然是运行的那个
MyPrg
MyClass
我的是.
我将其导入为“”。
我将其实例化为 .MyClass
MyClass.py
MyPrg.sage
from MyClass import MyClass
obj = MyClass()
在这之后,我得到”
importlib(MyClass)
TypeError: reload() argument must be a module
"
当您执行 时,您将从模块导入类。
但是,当您尝试使用 时,它需要一个模块作为参数,而不是一个类。因此,您将收到一个 .from MyClass import MyClass
MyClass
MyClass.py
importlib.reload(MyClass)
TypeError
处理导入的另一种方法是:importlib.reload()
- 修改 import 语句以导入模块,而不是直接从模块导入类。
MyPrg.sage
MyClass
- 然后,当您实例化时,您需要使用模块名称对其进行限定。
MyClass
- 最后,您可以使用重新加载模块。
importlib.reload()
import importlib
import MyClass # Import the module, not the class
# Instantiate MyClass from the module
obj = MyClass.MyClass()
# Do something
# Assume MyClass.py has been updated and you want to reload it:
importlib.reload(MyClass) # That will reload the module
# Now create a new instance, it will reflect the updated code:
new_obj = MyClass.MyClass()
这样,当您更改并重新运行时,该语句将重新加载更新的模块。
重新加载后创建的任何新实例都将反映更新后的代码。
该设置应处理您描述的场景,即您在运行之间进行更新,并希望在重新运行时使用更新的代码。MyClass.py
MyPrg.sage
importlib.reload(MyClass)
MyClass
MyClass
MyClass.py
MyPrg.sage
MyPrg.sage
OP 在评论中补充道:
我不需要创建新对象,因为我正在重新运行程序。
因此,我只是在第一次创建对象之前调用,这足以在重新运行程序时刷新类。importlib
obj = MyClass.Class()
这意味着每次运行时都会调用 ,确保在创建对象实例之前加载最新版本的 。对于所描述的方案,这是一个简单而有效的解决方案,其中程序正在重新运行,并且希望确保使用最新版本。importlib.reload()
MyPrg.sage
MyClass.py
MyClass.py
这与我建议的不同:一种允许在正在运行的程序中重新加载模块的结构,这可能比所描述的场景所需的更多。
评论
obj = MyClass.Class()
评论