<pre name="code" class="html">#coding=utf8
import sys
class _const(object):
class ConstError(TypeError):
pass
class ConstCaseError(ConstError):
pass
def __setattr__(self, name, value):
if self.__dict__.has_key(name):
raise self.ConstError, "Can't change const.%s" % name
self.__dict__[name] = value
# ref = sys.modules[__name__]
sys.modules[__name__] = _const()
# print sys, __name__
上面模块const.py
我们再写个conf.py
import const
const.NAME = 'name'
const.NAME = 'name' # raise value err
修改定义好的变量,按预期报错了。那么问题来了:
放开上文中屏蔽的, print出来的是None,None
再放开# ref = sys.modules[__name__]
print出来<module 'sys' (built-in)> __main__, 似乎知道什么。
结合:http://stackoverflow.com/questions/7121802/module-name-in-sys-modules-and-globals
大概意思是:重写sys.modules[__name__]的时候,sys模块被删除,因为它的引用为0,被回收了。返回None是因为Python把删除的模块全部设置成None
再看下面的代码,很好的说明,所有的import解释其全部放在sys.modules这个regular dict对象里面,包括sys,os等你import的,当我们重写sys.modules的时候,所有的import都是失效,相当于没有import,等价于执行del sys,os.
那么,按语法,使用没有import的模块应该报NameError(名字空间未定义),但是执行情况是打印了None.这是因为解释器问题,模块被删的时候,设置成空,与普通变量删除还是有点区别
class _test(): pass
import sys
import os
sys.modules[__name__] = _test()
# ref = sys.modules[__name__]
print sys # None, <module 'sys' (built-in)>
print os