Can a line of Python code know its indentation nesting level?
<p>From something like this:</p>

<pre><code>print(get_indentation_level())

    print(get_indentation_level())

        print(get_indentation_level())
</code></pre>

<p>I would like to get something like this:</p>

<pre><code>1
2
3
</code></pre>

<p>Can the code read itself in this way?</p>

<p>All I want is the output from the more nested parts of the code to be more nested. In the same way that this makes code easier to read, it would make the output easier to read. </p>

<p>Of course I could implement this manually, using e.g. <code>.format()</code>, but what I had in mind was a custom print function which would <code>print(i*' ' + string)</code> where <code>i</code> is the indentation level. This would be a quick way to make readable output on my terminal. </p>

<p>Is there a better way to do this which avoids painstaking manual formatting?</p>

<p>To solve the ârealâ problem that lead to your question you could implement a contextmanager which keeps track of the indention level and make the <code>with</code> block structure in the code correspond to the indentation levels of the output. This way the code indentation still reflects the output indentation without coupling both too much. It is still possible to refactor the code into different functions and have other indentations based on code structure not messing with the output indentation.</p>

<pre><code>#!/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()
</code></pre>

<p>Output:</p>

<pre><code>0
  1
    Hallo 2
      3
    and back one level 2
</code></pre>

python reflection metaprogramming indentation tokenize