Python静态变量
我正在创建一个应用程序,使用一个基础类来存放所有的配置值、导入方法等等。
/
- application.py
+ class foo
+ config = None
+ def loadconfig
- otherfile.py
+ class bar
+ def getconfigvalue
所以,如果我启动 application.py
并运行 loadconfig
,这个方法会把一个值加载到 foo.config
中,然后在这个方法里导入 otherfile.py
(这样做是为了避免循环导入),接着创建一个新的 bar
对象,这个对象尝试从 foo.config
中获取一个配置值,但却显示 foo.config
是 None。你有什么建议吗?
简化的代码:
main.py
class Main:
config = None
@staticmethod
def start():
## Load the configuration from a file, creating a dict in Main.config ##
Main.other()
@staticmethod
def other():
from otherfile import otherclass
otherclass()
Main.start()
otherfile.py
from main import Main
class otherclass:
def __init__(self):
print(Main.config) ## Prints "None"
注意:这样安排是因为这在程序中确实是这样工作的;我觉得这可能和作用域有关
完整的源文件:
asgard.py: http://pastebin.com/jRkWzrPq
library/childcontainer.py: http://pastebin.com/6a561Nun
1 个回答
我来帮你分析一下你在使用 asgard 时遇到的问题,因为你给的简单例子有点问题:
- 你不能运行
main.py
,这是因为有循环导入的问题。不过我觉得你是想运行main.py
(运行otherfile.py
不会出现你遇到的问题)。 - 你其实从来没有给
Main.config
赋值。我不太清楚你打算在哪里给它赋值。
好了,接下来谈谈 asgard.py
。
在这里你会遇到一个关于模块 __main__
的问题。当你运行 asgard.py
时,它的 __name__
是 __main__
;你可能不知道的是,这实际上就是它在 sys.modules
中的模块名称——主模块是 sys.modules['__main__']
,而不是 sys.modules['asgard']
。然后,当你导入 library.childcontainer
时,它会尝试导入 asgard
。这时它会查找 sys.modules['asgard']
,但这个模块不存在,所以它会把 asgard.py
的内容导入到一个新的模块对象中。
如果你有另一个文件 main.py
,里面写了 import asgard; asgard.Asgard.initialize()
(暂时不考虑我下面提到的条件导入问题),你就不会遇到这个问题,因为 __main__
模块会是那个 main.py
,而 asgard.py
只会以 asgard
的名字被导入。另一个可行的解决方案是 if __name__ == '__main__': sys.modules['asgard'] = sys.modules['__main__']
。
还有,请你一定要记住,不要使用 if __name__ == '__main__': import ...
这种方式。这意味着如果你尝试 import asgard; asgard.Asgard.initialize()
,比如说,它会失败并提示 'os' 未定义。请把这些导入放在文件的顶部,那里才是它们该在的位置。