python - 为什么分配给 sys.modules[__name__] 后 __name__ 的值会发生变化?

标签 python module

在尝试执行类似于 ActiveState 配方中标题为 Constants in Python 的操作时通过 Alex Martelli,我遇到了意想不到的副作用(在 Python 2.7 中),将类实例分配给 sys.modules 中的条目具有 - 即这样做显然会改变 __name__None 如下面的代码片段所示(它破坏了配方中的部分代码):

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"

我想了解为什么会这样。我不相信在 Python 2.6 和更早版本中是这样的,因为我有一些旧代码,显然 if __name__ == '__main__': 条件在分配后按预期工作(但不再做)。

FWIW,我还注意到名称 _test 在分配后也从类对象反弹到 None。我觉得奇怪的是它们被反弹到 None 而不是完全消失...

更新:

我想补充一点,对于实现 if __name__ == '__main__': 效果的任何变通方法,我们将不胜感激。蒂亚!

最佳答案

发生这种情况是因为您在执行 sys.modules[__name__] = _test() 时覆盖了您的模块,因此您的模块被删除了(因为该模块不再有任何对它的引用,并且引用计数器归零,所以它被删除了)但同时解释器仍然有字节码,所以它仍然可以工作,但是通过将 None 返回到模块中的每个变量(这是因为 python 设置删除时模块中的所有变量都为 None)。

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'>

希望这能说明问题。

关于python - 为什么分配给 sys.modules[__name__] 后 __name__ 的值会发生变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5365562/

相关文章:

python - 如何从 skopt/BayesSearchCV 搜索中绘制学习曲线

python - 在 SciPy 中将复杂函数的根存储在数组中

python - np.array 的 np.array 的深拷贝

perl - 为什么 Perl 模块 Crypt::SSLeay 在加载时出错?

arrays - NodeJS - 如何从模块返回数组

python - 在Python模块中运行无限while循环

python - 如何自定义 Tkinter 按钮

python - 在 Python 中将不同类型的对象分配给变量称为什么?

php - 从 php 模块读取文件失败,错误号 13

python - python 导入模块的问题