4

我正在尝试使用 Python 的自省模块inspect来检索已module_from_spec使用importlib.util. 尝试inspect.getsource()在 spec_file 本身或 spec 文件中的任何函数上使用都会成功返回所需的源代码。但是,用于检索规范文件中类类型的源代码的相同方法会抛出一个TypeError: None is a built-in class.

from importlib.util import spec_from_file_location, module_from_spec
spec_file = spec_from_file_location("file_module", 'test_file.py')
spec_module = module_from_spec(spec_file)
spec_file.loader.exec_module(spec_module)

# spec module
import inspect
assert isinstance(inspect.getsource(spec_module), str)

# function in spec module
func_obj = getattr(spec_module, 'test_function')
assert isinstance(inspect.getsource(func_obj), str)

# class in spec module
class_obj = getattr(spec_module, 'testClass')
try:
    inspect.getsource(class_obj)
except TypeError:
    print('where did the source code data go?')

罪魁祸首似乎是inspect.getfile()函数对象返回对象的回溯链中的调用。__code__而类对象尝试加载它们的模块以检索模块。__file__. 为什么函数有__code__方法,而类没有?这是 Python 如何处理无意中破坏动态加载类的自省的类型的副作用吗?

4

1 回答 1

3

看起来必须添加加载的模块才能sys.modules使源和模块路径正确反映在类中(尽管我无法在文档中找到对此的引用)。因此,如果您将sys模块导入并添加到sys.modules,您的示例应该可以工作(我用 Python 3.5 测试了一个类似的示例):

import sys

from importlib.util import spec_from_file_location, module_from_spec
spec_file = spec_from_file_location("file_module", 'test_file.py')
spec_module = module_from_spec(spec_file)
spec_file.loader.exec_module(spec_module)

sys.modules['file_module'] = spec_module

# spec module
import inspect
assert isinstance(inspect.getsource(spec_module), str)

# function in spec module
func_obj = getattr(spec_module, 'test_function')
assert isinstance(inspect.getsource(func_obj), str)

# class in spec module
class_obj = getattr(spec_module, 'testClass')
try:
    inspect.getsource(class_obj)  # This should work now
except TypeError:
    print('where did the source code data go?')
于 2017-05-03T18:13:32.140 回答