当直接运行以下脚本时,它会按预期运行:
import inspect
__module__ = "__main__"
__file__ = "classes.py"
test_str = "test"
class met(type):
def __init__(cls, name, bases, dct):
setattr(cls, "source", inspect.getsource(cls))
#setattr(cls, "source", test_str)
super(met, cls).__init__(name, bases, dct)
class ParentModel(object):
__metaclass__ = met
def __init__(self):
super(object, self).__init__(ParentModel.__class__)
def setsource(self):
self.source = inspect.getsource(self.__class__)
#self.source = test_str
def getsource(self):
return self.source
class ChildB(ParentModel):
name = "childb"
pass
class ChildA(ChildB):
name = "childa"
pass
class ChildC(ChildA):
name = "childc"
pass
尝试通过 python shell 或其他脚本中的 exec 或 execfile 运行此脚本时会出现困难。例如:
>>> execfile("classes.py")
运行没有问题,但是:
>>> ns = {}
>>> execfile("classes.py", ns)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "classes.py", line 13, in <module>
class ParentModel(object):
File "classes.py", line 9, in __init__
setattr(cls, "source", inspect.getsource(cls))
File "D:\Python27\lib\inspect.py", line 701, in getsource
lines, lnum = getsourcelines(object)
File "D:\Python27\lib\inspect.py", line 690, in getsourcelines
lines, lnum = findsource(object)
File "D:\Python27\lib\inspect.py", line 526, in findsource
file = getfile(object)
File "D:\Python27\lib\inspect.py", line 408, in getfile
raise TypeError('{!r} is a built-in class'.format(object))
TypeError: <module '__builtin__' (built-in)> is a built-in class
这会导致错误,因为 execfile 的全局命名空间参数接受了字典,这会造成混淆。但:
>>> execfile("classes.py", globals())
同样,运行没有问题,但:
>>> ns = dict(globals())
>>> execfile("classes.py", ns)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "classes.py", line 13, in <module>
class ParentModel(object):
File "classes.py", line 9, in __init__
setattr(cls, "source", inspect.getsource(cls))
File "D:\Python27\lib\inspect.py", line 701, in getsource
lines, lnum = getsourcelines(object)
File "D:\Python27\lib\inspect.py", line 690, in getsourcelines
lines, lnum = findsource(object)
File "D:\Python27\lib\inspect.py", line 526, in findsource
file = getfile(object)
File "D:\Python27\lib\inspect.py", line 408, in getfile
raise TypeError('{!r} is a built-in class'.format(object))
TypeError: <module '__builtin__' (built-in)> is a built-in class
从回溯来看,它与检查有关,但是它也应该在 execfile("classes.py") 或 execfile("classes.py", globals()) 上出错。
那么,就这个错误而言, dict(globals()) != globals() 怎么样,为什么会导致这个错误?
编辑:读者应该参考 Martijn Pieters 和 Lennart Regebro 的答案以获得完整的图片。