我将sys.modules[__name__]
修改为类Hello
,如下所示:
# hello.py
import sys
import time
class Hello:
def print_time(self):
print 'hello, current time is:', time.time()
sys.modules[__name__] = Hello()
然后,我在另一个python文件hello.py
中导入了test.py
,如:
# test.py
import hello
hello.print_time()
但是,当我运行"AttributeError: 'NoneType' object has no attribute 'time'"
时,我收到错误python test.py
。
似乎hello.py
无法导入time
模块。
我真的没有弄清楚问题。
我该如何解决?
答案 0 :(得分:5)
事实证明,NightShadeQueen是正确的,问题是原始模块对象是垃圾收集 - 但问题仍然存在,为什么它有这种行为?也就是说,它仍然记录了 所做的全局 - 引用从未导入的内容为您提供NameError
,而所做的一切< / em>现在是None
。我挖到了源头找出来。
模块是一个对象。与许多对象一样,它有一个__dict__
,存储没有显式插槽的所有属性。创建全局对象时,它们将添加到此字典中。
创建函数时,它会在定义时维护对globals字典的引用。它不维护对拥有该字典的模块的引用 - 它仅维护对字典本身的引用。
由于某种原因,模块的终结器清除了它的字典。 (请参阅the source。)不是删除批量密钥,而是用None
替换它们,这条评论说明它避免重复字典。
坦率地说,我不明白为什么模块终结器需要这样做;它可以合理地删除它对字典的引用,让字典处理删除对其值的引用。
答案 1 :(得分:4)
由于模块 time
hello
不再有任何指向它的引用,因此它被垃圾收集。这意味着你失去了全局。
一个稍微糟糕的修复:将其附加到班级Hello
。
import sys
class Hello:
import time #Yes, the import statement in the class.
def print_time(self):
print 'hello, current time is:', time.time()
sys.modules[__name__] = Hello()