首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >一行Python代码可以知道它的缩进嵌套级别吗?

一行Python代码可以知道它的缩进嵌套级别吗?
EN

Stack Overflow用户
提问于 2016-08-27 02:07:25
回答 4查看 8.8K关注 0票数 150

从类似这样的东西:

代码语言:javascript
复制
print(get_indentation_level())

    print(get_indentation_level())

        print(get_indentation_level())

我想得到这样的东西:

代码语言:javascript
复制
1
2
3

代码能以这种方式自行读取吗?

我想要的是代码中嵌套较多的部分的输出更加嵌套。以同样的方式,这将使代码更容易阅读,它将使输出更容易阅读。

当然,我可以手动实现这一点,例如使用.format(),但我想到的是一个自定义打印函数,它将print(i*' ' + string),其中i是缩进级别。这将是在我的终端上生成可读输出的一种快速方法。

有没有更好的方法来避免费力的手动格式化?

EN

回答 4

Stack Overflow用户

发布于 2016-08-27 02:23:18

是的,这绝对是可能的,这是一个有效的例子:

代码语言:javascript
复制
import inspect

def get_indentation_level():
    callerframerecord = inspect.stack()[1]
    frame = callerframerecord[0]
    info = inspect.getframeinfo(frame)
    cc = info.code_context[0]
    return len(cc) - len(cc.lstrip())

if 1:
    print get_indentation_level()
    if 1:
        print get_indentation_level()
        if 1:
            print get_indentation_level()
票数 22
EN

Stack Overflow用户

发布于 2016-08-27 02:21:24

您可以使用sys.current_frame.f_lineno来获取行号。然后,为了找到缩进级别的数量,您需要找到前一行的缩进为零,然后从该行的编号中减去当前行号,得到缩进的数量:

代码语言:javascript
复制
import sys
current_frame = sys._getframe(0)

def get_ind_num():
    with open(__file__) as f:
        lines = f.readlines()
    current_line_no = current_frame.f_lineno
    to_current = lines[:current_line_no]
    previous_zoro_ind = len(to_current) - next(i for i, line in enumerate(to_current[::-1]) if not line[0].isspace())
    return current_line_no - previous_zoro_ind

演示:

代码语言:javascript
复制
if True:
    print get_ind_num()
    if True:
        print(get_ind_num())
        if True:
            print(get_ind_num())
            if True: print(get_ind_num())
# Output
1
3
5
6

如果您想使用:根据前面的行缩进级别的数量,只需稍微更改一下即可:

代码语言:javascript
复制
def get_ind_num():
    with open(__file__) as f:
        lines = f.readlines()

    current_line_no = current_frame.f_lineno
    to_current = lines[:current_line_no]
    previous_zoro_ind = len(to_current) - next(i for i, line in enumerate(to_current[::-1]) if not line[0].isspace())
    return sum(1 for line in lines[previous_zoro_ind-1:current_line_no] if line.strip().endswith(':'))

演示:

代码语言:javascript
复制
if True:
    print get_ind_num()
    if True:
        print(get_ind_num())
        if True:
            print(get_ind_num())
            if True: print(get_ind_num())
# Output
1
2
3
3

作为替代答案,下面是一个用于获取缩进数量(空格)的函数:

代码语言:javascript
复制
import sys
from itertools import takewhile
current_frame = sys._getframe(0)

def get_ind_num():
    with open(__file__) as f:
        lines = f.readlines()
    return sum(1 for _ in takewhile(str.isspace, lines[current_frame.f_lineno - 1]))
票数 10
EN

Stack Overflow用户

发布于 2016-08-28 21:46:20

要解决导致您的问题的“实际”问题,您可以实现一个上下文管理器,它跟踪缩进级别,并使代码中的with块结构与输出的缩进级别相对应。这样,代码缩进仍然反映了输出缩进,而不会将两者过度耦合。仍然可以将代码重构为不同的函数,并根据代码结构进行其他缩进,而不会影响输出缩进。

代码语言:javascript
复制
#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function


class IndentedPrinter(object):

    def __init__(self, level=0, indent_with='  '):
        self.level = level
        self.indent_with = indent_with

    def __enter__(self):
        self.level += 1
        return self

    def __exit__(self, *_args):
        self.level -= 1

    def print(self, arg='', *args, **kwargs):
        print(self.indent_with * self.level + str(arg), *args, **kwargs)


def main():
    indented = IndentedPrinter()
    indented.print(indented.level)
    with indented:
        indented.print(indented.level)
        with indented:
            indented.print('Hallo', indented.level)
            with indented:
                indented.print(indented.level)
            indented.print('and back one level', indented.level)


if __name__ == '__main__':
    main()

输出:

代码语言:javascript
复制
0
  1
    Hallo 2
      3
    and back one level 2
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39172306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档