python – 有没有办法将上下文管理器中的源代码作为字符串?

使用inspect.getsourcelines(func)函数接收函数
can be的源代码.有没有办法为上下文管理器做同样的事情?

with test():
    print('123')

# How to get "print('123')" as line here?

最佳答案 您对此解决方案有何看法?

import traceback


class ContextManagerContent(object):

    def __enter__(self):
        return

    def __exit__(self, _type, value, _traceback):
        stack = traceback.extract_stack()
        f, last_line = self._get_origin_info(stack)

        with open(f) as fin:
            lines = list(fin)

        search = 'with {cls_name}'.format(cls_name=self.__class__.__name__)
        for i, x in enumerate(lines[:last_line + 1][::-1]):
            if search in x:
                first_line = len(lines) - i
                break

        selected_lines = lines[first_line:last_line + 1]
        print ''.join(selected_lines)

    def _get_origin_info(self, stack):
        origin = None
        for i, x in enumerate(stack[::-1]):
            if x[2] == '__exit__':
                origin = stack[::-1][i + 1]
                break

        return origin[0], origin[1] - 1


with ContextManagerContent():
    print '123'
    print '456'
    print '789'

如果将其保存在.py文件中并运行它,您可以看到打印数字123,456和789,之后您可以看到上下文管理器的块.

请注意,我没有处理可能的异常或输出格式,有些部分可以改进,但我认为这是一个很好的起点.

点赞