更新后如何重新加载导入? Sage 似乎直到会话结束才重新加载它

问题描述 投票:0回答:1

我有一个名为

MyClass.py
的文件,其中包含一个类
MyClass
。 我有一个
MyPrg.sage
将其导入为

  from MyClass import MyClass

然后实例化

MyClass
并调用它的方法。

我通过调用

MyPrg.sage
通过 sage 控制台运行
load
。如果程序退出后,我更改
MyClass.py
并通过
MyPrg.sage
再次重新运行
load
,它似乎使用旧的
MyClass.py
。让它运行更新后的类的唯一方法是杀死 shell 并在新 shell 中运行它。

有没有办法告诉 Sage 重新加载更新后的导入?

我在 Windows 10 上运行 Sage 9.3。

python-import reload sage
1个回答
0
投票

在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()

通过此设置,每次调用

importlib.reload(MyClass)
时,Python 都会从
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
  1. MyPrg
  2. 执行完毕
    我更新
  3. MyClass
  4. 我重新运行
  5. MyPrg
  6. ,较旧的
    MyClass
    似乎仍然是正在运行的
    
    
  7. 我的
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()

中的导入语句以导入模块
    MyPrg.sage
  1. ,而不是直接从模块导入类。
    然后,当您实例化
    MyClass
    时,您将需要使用模块名称来限定它。
  2. 最后,您可以使用
    MyClass
    重新加载模块。
  3. importlib.reload()
  4. 这样,当您对
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
时使用更新的代码。
    

© www.soinside.com 2019 - 2024. All rights reserved.