Python inspect.stack()的code_context只返回一行上下文

问题描述 投票:0回答:2
import inspect

def a(x, y, z):
  frame = inspect.stack()[1]
  print(frame.code_context)

def b():
  a(
    1,
    2,
    3,
  )

b()

>> ['    3,\n']

为什么code_context只返回最后一行?documentation说code_context是“ 源代码中的上下文行列表

我希望code_context包含以下内容:

[
  '    1,\n',
  '    2,\n',
  '    3,\n',
]

我想获得all上下文行。

python python-3.x inspect
2个回答
1
投票

对于保留空格和注释的健壮解决方案,您可以使用lib2to3模块从父文件中解析和抓取所有简单的语句节点(在simple_stmt中以Python语法在Grammar.txt中表示)。框架所属的节点,并返回其起始行号和行数(通过计算换行符的数量计算)覆盖框架的行号的节点:

from lib2to3 import fixer_base, refactor

class ScrapeStatements(fixer_base.BaseFix):
    PATTERN = 'simple_stmt'

    def __init__(self, *args):
        super().__init__(*args)
        self.nodes = []

    def transform(self, node, _):
        self.nodes.append(node)
        return node

class Refactor(refactor.RefactoringTool):
    def get_fixers(self):
        self.scraper = ScrapeStatements(None, None)
        return [self.scraper], []

    def get_result(self, lineno):
        return next(node for node in self.scraper.nodes
            if lineno - node.get_lineno() < str(node).count('\n'))

这样:

import inspect

def a(x, y, z):
    frame = inspect.stack()[1].frame
    refactor = Refactor(None)
    refactor.refactor_string(open(frame.f_code.co_filename).read(), '')
    print(refactor.get_result(frame.f_lineno))

def b():
    a(
        1,
        2,
        3,
    )

b()

输出:

a(
        1,
        2,
        3,
    )

演示:https://repl.it/@blhsing/HotpinkOpenCgibin

但是,从上面的输出中可以看到,此方法的次要缺点是,如果语句节点位于代码块的开头,则该语句节点将不包含前面的缩进。


0
投票

不幸的是,Python解释器为每个帧只保留一个行号。查看整个代码上下文的一种相对简单且健壮的方法是使用出色的uncompyle6模块对代码对象进行反编译。由于代码对象不保留空格和注释,因此您将看到原始代码的更紧凑版本作为反编译输出:

uncompyle6

此输出:

import inspect
from io import StringIO
from uncompyle6 import deparse_code2str

def a(x, y, z):
    frame = inspect.stack()[1]
    code = StringIO()
    deparse_code2str(frame.frame.f_code, out=code)
    print(code.getvalue())

def b():
    a(
        1,
        2,
        3,
    )

b()

演示:a(1, 2, 3)

© www.soinside.com 2019 - 2024. All rights reserved.