【问题标题】:Source info missing from python classes loaded with module_from_spec使用 module_from_spec 加载的 python 类中缺少源信息
【发布时间】:2017-05-04 02:23:46
【问题描述】:

我正在尝试使用 Python 的自省模块 inspect 来检索已使用 importlib.utilmodule_from_spec 函数加载到作用域中的活动对象的源代码。尝试在 spec_file 本身或 spec 文件中的任何函数上使用 inspect.getsource() 成功返回所需的源代码。但是,用于检索规范文件中类类型的源代码的相同方法会引发 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() 调用,其中函数对象返回 object.__code__,而类对象试图加载其模块以检索模块。__file__。为什么函数有__code__ 方法,而类没有?这是 Python 如何处理无意中破坏动态加载类的自省的类型的副作用吗?

【问题讨论】:

    标签: python introspection inspect python-importlib


    【解决方案1】:

    看起来必须将加载的模块添加到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?')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-05
      • 1970-01-01
      • 2013-12-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-21
      • 2017-05-19
      • 1970-01-01
      相关资源
      最近更新 更多