分配给sys.modules [__ name__]后,为什么__name__的值会发生变化? [英] Why is the value of __name__ changing after assignment to sys.modules[__name__]?

查看:714
本文介绍了分配给sys.modules [__ name__]后,为什么__name__的值会发生变化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在尝试执行与ActiveState食谱中标题为 Python (由Alex Martelli编写),我遇到了意想不到的副作用(在python 2.7中),即为sys.modules中的条目分配类实例具有-即,这样做显然会将__name__的值更改为None,如以下代码片段所示(破坏了食谱中的部分代码):

While trying to do something similar to what's in the ActiveState recipe titled Constants in Python by Alex Martelli, I ran into the unexpected side-effect (in Python 2.7) that assigning a class instance to an entry in sys.modules has -- namely that doing so apparently changes the value of __name__ to None as illustrated in the following code fragment (which breaks part of the code in the recipe):

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__':条件在分配后按预期工作了(但不再这样做了).

I'd like to understand why this is happening. I don't believe it was that way in Python 2.6 and earlier versions since I have some older code where apparently the if __name__ == '__main__': conditional worked as expected following the assignment (but no longer does).

FWIW,我还注意到,赋值后,名称_test也正从类对象反弹到None.我觉得奇怪的是,他们正在反弹到None而不是完全消失...

FWIW, I also noticed that the name _test is getting rebound from a class object to None, too, after the assignment. It seems odd to me that they're being rebound to None rather than disappearing altogether...

更新:

我想补充一点,鉴于发生的任何情况,实现if __name__ == '__main__':效果的任何变通办法将不胜感激. TIA!

I'd like to add that any workarounds for achieving the effect of if __name__ == '__main__':, given what happens would be greatly appreciated. TIA!

推荐答案

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

This happens because you have overwrite your module when you did sys.modules[__name__] = _test() so your module was deleted (because the module didn't have any references to it anymore and the reference counter went to zero so it's deleted) but in the mean time the interpreter still have the byte code so it will still work but by returning None to every variable in your module (this is because python sets all the variables to None in a module when it's deleted).

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.

将通过以下方式进行修复:

A fix will be by doing like this:

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

希望这会解释问题.

这篇关于分配给sys.modules [__ name__]后,为什么__name__的值会发生变化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆