繁体   English   中英

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

[英]Why is the value of __name__ changing after assignment to sys.modules[__name__]?

在尝试执行类似于Alex Martelli的ActiveState食谱(名为Python中Constants)的方法时 ,我遇到了意外的副作用(在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__':达到if __name__ == '__main__':的效果,可以采取任何变通办法。 TIA!

发生这种情况的原因是,您在执行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'>

希望这能解释一切。

如果我为sys.modules['__main__']分配任何内容, sys.modules['__main__']导致严重破坏的环境。 不是这种确切的行为,但是我所有的全局变量和内置函数都消失了。

并未记录sys.modules在写入时会表现出任何特定的行为,只是隐约地可以将其用于“重载技巧”(甚至有一些重要的陷阱)。

我不会写一个非模块的东西,除了痛苦之外,别无他法。 我认为这个食谱是完全错误的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM