Python 为什么分配给sys.modules[\uuuuuuu name\uuuuu]后,\uuuuu name\uuuuu的值会发生变化?
在尝试做一些类似于Alex Martelli命名的ActiveState配方的事情时,我遇到了意想不到的副作用(在Python 2.7中)将类实例分配给Python 为什么分配给sys.modules[\uuuuuuu name\uuuuu]后,\uuuuu name\uuuuu的值会发生变化?,python,module,Python,Module,在尝试做一些类似于Alex Martelli命名的ActiveState配方的事情时,我遇到了意想不到的副作用(在Python 2.7中)将类实例分配给sys.modules中的一个条目具有--即这样做显然会将\uuuuuu name\uuuuuu的值更改为None,如以下代码片段所示(这会打断配方中的部分代码): 我想知道为什么会这样。我不相信在Python2.6和更早的版本中是这样的,因为我有一些较旧的代码,其中显然if\uuuu name\uuuu=='\uuuu main\uuuu':c
sys.modules
中的一个条目具有--即这样做显然会将\uuuuuu name\uuuuuu
的值更改为None
,如以下代码片段所示(这会打断配方中的部分代码):
我想知道为什么会这样。我不相信在Python2.6和更早的版本中是这样的,因为我有一些较旧的代码,其中显然if\uuuu name\uuuu=='\uuuu main\uuuu':
conditional在赋值后按预期工作(但不再如此)
FWIW,我还注意到名称\u test
在赋值之后也从类对象反弹到None
。我觉得奇怪的是,他们被反弹到没有,而不是完全消失
更新:
我想补充一点,如果uuu name uuuuu=='uuuu main uuu':,如果能实现
的效果,我们将不胜感激。蒂亚 如果我将任何东西分配给系统模块['''u____']
我会得到一个严重破坏的环境。不是这样的行为,但我所有的球和内置物都消失了
sys.modules
在写入时没有任何特定的行为记录,只是模糊地表示您可以将其用于“重新加载技巧”(甚至在这种用法中也存在一些明显的陷阱)
我不会给它写一个非模块,除了痛苦之外,我什么都不会期待。我认为这个方法是完全错误的。发生这种情况的原因是,当您执行sys.modules[\uu name\uuu]=\ u test()时,您已经覆盖了您的模块,因此您的模块被删除(因为模块不再有任何引用,并且引用计数器变为零,所以被删除)但是与此同时,解释器仍然有字节码,因此它仍然可以工作,但是通过向模块中的每个变量返回
None
(这是因为python在删除模块时将模块中的所有变量设置为None
)
class\u测试(对象):通过
导入系统
打印系统模块[''.'主'.']
#“用无覆盖一切”行为来自模块析构函数故意清除模块中定义的函数和模块中定义的函数之间的引用循环。回答不错,解决方法也很好。我从未考虑过删除对模块的sys.modules[]
引用会导致其立即销毁,因为其引用计数将为零(特别是考虑到它是由模块本身中的代码完成的)。谢谢根据您的解决方案建议,我已将sys.modules[\uuuuu name\uuuu]=\u test()
替换为\u ref,sys.modules[\uuuu name\uuuuuuuuu]=sys.modules[\uuu name\uuuuuuuuu]、\uu test()
,一切看起来都很好。@martineau:很高兴这是有用的:)ref=sys.modules[''''uuu main\uuuuuuuuu']
在导入时损坏。在python REPL中应该是ref=sys.modules[\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\。。。当然,每次在sys模块中写入内容时,都应该注意“这里是龙”。-)
class _test(object): pass
import sys
print '# __name__: %r' % __name__
# __name__: '__main__'
sys.modules[__name__] = _test()
print '# __name__: %r' % __name__
# __name__: None
if __name__ == '__main__': # never executes...
import test
print "done"
class _test(object): pass
import sys
print sys.modules['__main__']
# <module '__main__' from 'test.py'> <<< the test.py is the name of this module
sys.modules[__name__] = _test()
# Which is the same as doing sys.modules['__main__'] = _test() but wait a
# minute isn't sys.modules['__main__'] was referencing to this module so
# Oops i just overwrite this module entry so this module will be deleted
# it's like if i did:
#
# import test
# __main__ = test
# del test
# __main__ = _test()
# test will be deleted because the only reference for it was __main__ in
# that point.
print sys, __name__
# None, None
import sys # i should re import sys again.
print sys.modules['__main__']
# <__main__._test instance at 0x7f031fcb5488> <<< my new module reference.
class _test(object): pass
import sys
ref = sys.modules[__name__] # Create another reference of this module.
sys.modules[__name__] = _test() # Now when it's overwritten it will not be
# deleted because a reference to it still
# exists.
print __name__, _test
# __main__ <class '__main__._test'>