您尝试实现的内容存在一些问题,除非您是有意设置了一个自修改代码系统,但看起来您并没有这样做。
1. 全局变量
spam = 100
def set_spam(value):
spam = value
foo = reload(foo)
这样做不会起作用。由于 Python 闭包的工作原理,你的 spam = value
代码会在 set_spam
函数内创建一个新的本地变量 spam
,而这个变量将不会被使用。要正确更改全局变量 spam
的值,您必须使用 global
关键字,如下所示:
spam = 100
def set_spam(value):
global spam
spam = value
2. 重新加载模块“自身”
据我所知,实际上没有办法做到这一点,也不应该需要。您已经导入的任何模块都是从其他模块调用的,直至__main__
。您只需从调用模块刷新它即可。是的,您可以尝试自我导入模块(尽管可能存在无限循环问题,如mgilson所提到的),但是即使是这样(使用名为“foo”的示例),如果您让它导入自身,则只会有foo.foo
,并且执行类似于foo.reload(foo)
的操作(如果这个有效的话)只会重新加载子级foo
,而不是基本的那一个。
3. 重新加载foo.py
spam = 100
def set_spam(value):
global spam
spam = value
请注意,在代码的顶部,您将100分配给spam
。每次导入模块时,您都会再次执行此操作。因此,即使您已经在导入foo
的代码中更改了spam
的值,当您重新加载模块时,实际上您将销毁刚刚进行的更改。例如:
>>> import foo
>>> foo.spam
100
>>> foo.spam = 9
>>> foo.spam
9
>>> reload(foo)
>>> foo.spam
100
因此,如果您希望保留在foo
变量中所做的更改,则不应该重新加载模块。此外,您甚至不需要使用set_spam
函数来更改spam
,您可以像我所做的那样直接设置它。
4. 尝试在其他模块中使用“更改后”的模块值
最后,如果我正确理解了您想要做的事情,那是行不通的。这在很大程度上是由于我在第三部分提到的一些事情,其中每次您加载foo
时,spam = 100
行将重置spam
的值。同样,如果您在两个不同的其他模块中导入foo
模块,当每个模块导入它时,它们都将独立地从spam = 100
开始,而与其他模块对foo.spam
的处理完全无关。例如,如果bar1.py
和bar2.py
中都包含import foo
行:
>>> import bar1, bar2
>>> bar1.foo.spam
100
>>> bar2.foo.spam
100
>>> bar1.foo.spam = 200
>>> bar1.foo.spam
200
>>> bar2.foo.spam
100
如果您能更详细地解释你想要做的事情,我们可以帮助您重构代码以使其更好地工作。
set_spam
函数的顶部使用global spam
,但我不完全清楚你为什么认为重新加载可以保持值为200。如果有什么作用,它会在设置后立即将其重置为100,这毫无意义。 - Wooblereload(module)
更好。 - Kermit