2

In free-form languages, sometimes I use indentation to represent some implicit structure in my statements. In the following example, I'm just doing a sequence of prints but the indentation indicates that the first and fourth print statements are "bracketing" the two in the middle.

print("<div>")
  print("hello")
  print("world")
print("</div>")

Is there a way to do something similar in Python without triggering an IndentationError: unexpected indent?

So far, the best I could think is to use a vacuous if statement to introduce a new indentation level.

print("<div>")
if True:
  print("hello")
  print("world")
print("</div>")
hugomg
  • 68,213
  • 24
  • 160
  • 246
  • 1
    I am a bit confused on why you would like to add nesting to your code. I do not think the added indents on the two prints improves the readability. Also this seems to be against the style-code defined in the PEP and python programmers are obsessed about the style-code. – JDurstberger Feb 12 '16 at 07:17
  • Well, you can, same as you can write a code in C++ that would not compile. Syntax errors are syntax errors - and in Python indentation IS a part of syntax. – Łukasz Rogalski Feb 12 '16 at 07:21
  • I want to add nesting because if I print everything flat then there is no way to see the actual structure behind the print statements. Maybe there is a nice way to use an `with` statement to surround a code block with an a pair of implicit prints? I just noticed that the "bracketing" prints are always the same – hugomg Feb 12 '16 at 07:22
  • While it doesn't address your question, using template files would be an option. They are basically HTML stripped off the variable parts. Loading them as HTML even gives you syntax highlighting then. – Ulrich Eckhardt Feb 12 '16 at 07:27
  • @UlrichEckhardt: the HTML was just an example. My real question is more general ([the answer I accepted](http://stackoverflow.com/a/35356921/90511) has an opengl example that I think better illustrates the problem) – hugomg Feb 12 '16 at 07:31

2 Answers2

6

I, too, remember sometimes wanting such structure. This is what comes to mind (in C code that allows this mis-indentation):

glBegin(GL_TRIANGLES);
    drawVertices();
glEnd();

Note that we have a begin and an end, and from here on I'm going to assume that the same happens in your case: you want to denote the beginning and ending of something. Another situation would be opening and closing a file, or even the example in your question. Python has a specific feature for this: context managers. Python's documentation even has an example with exactly this:

(this is not recommended as a real way of generating HTML!):

from contextlib import contextmanager

@contextmanager
def tag(name):
    print("<%s>" % name)
    yield
    print("</%s>" % name)

>>> with tag("h1"):
...    print("foo")
...
<h1>
foo
</h1>

I have to mention that context managers aren't simply a way to restructure your code, they can actually act on exceptions raised from the enclosed code, and execute some code regardless of the exception (e.g. to ensure that a file is closed). With the simple examples using @contextmanager this does not happen because its default behavior is to simply re-raise the exception so no surprises happen.


Other than this, the people you work with will not be happy about the false indentation. If you insist on it, sure, if True is an option.

Community
  • 1
  • 1
Oleh Prypin
  • 33,184
  • 10
  • 89
  • 99
4

In general, no, indentation is significant in Python.

Some alternatives that you can use are comments and line spacing:

print("start")

print("middle1")
print("middle2")

print("end")

or

# Header
print("start")
# Middle
print("middle1")
print("middle2")
# End
print("end")

You could also consider breaking your code up into sub-functions, if it makes sense to do so.

def printMiddle():
    print("middle1")
    print("middle2")

print("start")
printMiddle()
print("end")

However, for the specific use-case of generating nested output (like HTML), I'd suggest using a templating library instead; writing raw HTML via string manipulation can lead to both hassle and bugs (especially when things like escaping of values is involved).

Amber
  • 507,862
  • 82
  • 626
  • 550