Python コードの行はインデントのネストレベルを知ることができますか? 質問する

Python コードの行はインデントのネストレベルを知ることができますか? 質問する

次のようなものです:

print(get_indentation_level())

    print(get_indentation_level())

        print(get_indentation_level())

次のようなものを取得したいです:

1
2
3

コードはこのようにして自分自身を読み取ることができますか?

私が望んでいるのは、コードのネストされた部分からの出力をさらにネストすることです。これによりコードが読みやすくなるのと同じように、出力も読みやすくなります。

もちろん、たとえば を使ってこれを手動で実装することもできます.format()が、私が考えていたのは、インデント レベルがprint(i*' ' + string)どこにあるかを示すカスタム プリント関数でしたi。これは、端末上で読み取り可能な出力を素早く作成する方法です。

面倒な手動フォーマットを回避できる、より良い方法はありますか?

ベストアンサー1

スペースやタブではなく、ネスト レベルでインデントを行う場合、状況は複雑になります。たとえば、次のコードでは次のようになります。

if True:
    print(
get_nesting_level())

get_nesting_level呼び出しの行の先頭に空白がないにもかかわらず、呼び出しは実際には 1 レベル深くネストされていますget_nesting_level。一方、次のコードでは:

print(1,
      2,
      get_nesting_level())

get_nesting_level行の先頭に空白があるにもかかわらず、の呼び出しは0 レベルの深さにネストされています。

次のコードでは:

if True:
  if True:
    print(get_nesting_level())

if True:
    print(get_nesting_level())

get_nesting_level先頭の空白は同じであるにもかかわらず、 の2 つの呼び出しは異なるネスト レベルにあります。

次のコードでは:

if True: print(get_nesting_level())

INDENTこれはネストされたレベルが 0 ですか、それとも 1 ですか? 正式な文法のトークンに関してはDEDENT、ネストされたレベルは 0 ですが、同じようには感じないかもしれません。


これを実行するには、呼び出しの時点までファイル全体をトークン化し、トークンINDENTをカウントする必要がありますDEDENTtokenizeモジュールはこのような機能に非常に役立ちます:

import inspect
import tokenize

def get_nesting_level():
    caller_frame = inspect.currentframe().f_back
    filename, caller_lineno, _, _, _ = inspect.getframeinfo(caller_frame)
    with open(filename) as f:
        indentation_level = 0
        for token_record in tokenize.generate_tokens(f.readline):
            token_type, _, (token_lineno, _), _, _ = token_record
            if token_lineno > caller_lineno:
                break
            elif token_type == tokenize.INDENT:
                indentation_level += 1
            elif token_type == tokenize.DEDENT:
                indentation_level -= 1
        return indentation_level

おすすめ記事