Mixing Tabs & Spaces
Trey Hunner / @treyhunner
My name is Trey. I do corporate training and I teach online. My primary programming specialty is Python.
I'm going to teach you how to mix and tabs when indenting your Python code.
Indentation
Programmers use indentation to make code readable
Python uses indentation to define code blocks
Python allows either tabs or spaces for indentation
Why not both? 😈
As programmers, we use indentation to **make our code readable**.
Unlike most other programming languages, Python actually **cares about our indentation**.
It uses indentation to **figure out what our code blocks look like**.
In Python, we can use **either spaces or tabs** for indentation.
But what if we didn't want to choose between tabs and spaces? What if we couldn't decide?
What if we used a **mix of both tabs and spaces**?
Some programmers just want to mix tabs and spaces
You're probably wondering what kind of indecisive fool would *mix* tabs and spaces.
That's not what I'm going to talk about though.
I'm not going to tell you why you should mix tabs and spaces, I'm only going to **show you HOW**.
Indentation doesn't always matter
def flatten(matrix):
return [
n for row
in matrix for n
in row
]
def len_or_none(obj):
try:
return len(obj)
except TypeError:
return None
First we need to talk about indentation.
Indentation doesn't always matter as much as you might think.
If you're continuing a line by leaving open a parenthesis, bracket, or brace, the indentation doesn't matter at all
If you're making a **new** indentation level to start a new block of indented code, that first line of code only needs to have greater indentation.
It doesn't matter whether it aligns with some previously indented-block. It just needs to be greater.
Same block? Indentation matters.
def guess_number():
while True:
guess = input('Guess: ')
if guess == '4':
break
def len_or_none(obj):
try:
return len(obj)
except TyperError:
return None
However, indentation often does matter.
If you're in the **same code block**, your **indentation level must remain the same**. You can't remove a space, you can't add a space.
That `if` statement on the left is not lined up with the `guess` variable but it's also not at the same level as the `while` so it's not inside the `while` block but it's also not outside it. That is broken code.
That `except` line on the right isn't in the same block as the `try`, but it's supposed to be. That's also broken code.
Indentation rules for each line of code
Same block : last line's indentation level
Outer block : a previous less-indented level
New block : more indented than current indentation
If a line of code is in the **same block** as the previous line it must be **indented the same amount**.
If a line of code is supposed to **end the current block** by being outside of it, it must **line up with a previous indentation level**.
If a line of code is forming a **new code block** (for example the first line of an `if` or a `while`) it must be **more indented** than the last line of code.
What about tabs and spaces?
Typewriters: tab key moves the cursor to the next tab stop
In Python, there's a tab stop at every 8 characters
1 tab character = number of spaces until the next tab stop
Those indentation rules are great, but what about mixing tabs and spaces?
When using tabs it's important to keep in mind that tab characters represent the number of characters until the next 8 character tab stop.
Sometimes we can approximate this idea by saying that tabs are equal to 8 spaces. But that's not quite true.
Let's take a look at some code to see why that is.
Tab stops are 8 characters
def guess_number():
while True:
guess = input('Guess: ')
if guess == '4':
break
def guess_number():
while True:
guess = input('Guess: ')
if guess == '4':
break
The indentation in these code blocks is highlighted. Every space character is blue and every tab character is red.
These two code samples are equivalent. In the code block on the right you can see that those 8 spaces are seen as equivalent to that 1 tab character.
We can use them interchangeably.
Tabs: not always 8 spaces
def guess_number():
while True:
guess = input('Guess: ')
if guess == '4':
break
def guess_number():
while True:
guess = input('Guess: ')
if guess == '4':
break
These two code blocks are also equivalent.
Note that on the right, the `if` statement line is indented with 4 spaces and 1 tab, but Python sees this as equivalent to 8 spaces.
There is a tab stop every 8 characters in Python.
Tab *characters* only **fill the space needed** to reach the **next tab stop**.
def progressively_more_spaces():
print("let's add one more space to the beginning...")
print("of each line.")
print("The effective indentation is the same")
print("even though we're adding more spaces.")
print("Each tab represents only the spaces needed")
print("to get to the next 8 character tab stop.")
if "your editor doesn't use 8 character tabs":
print("you may have trouble reading this code.")
print("Python uses 8 character tab stops")
print("so we also use 8 character tab stops.")
print("This way we can mix spaces and tabs")
print("without any worries about broken code.")
print("Mixing tabs and spaces can be fun")
print("but beware!")
while "you could write code like this":
print("It's probably best not to.")
A line of code with **1 tab** is equivalent to a line of code with **1 space and 1 tab**.
This is also equivalent to **2 spaces and 1 tab** or **7 spaces and 1 tab**.
**8 spaces and one tab** is the same as **2 tabs** or **16 spaces**.
Configure your editor
# http://editorconfig.org
[*.py]
indent_size = 4
tab_width = 8
indent_style = tab
This is very important: if you are mixing tabs and spaces, you must configure your text editor to use tab stops that are 8 characters wide.
Don't use Python 3
$ python3 examples/demo.py
File "examples/demo.py", line 3
print("of each line.")
^
TabError: inconsistent use of tabs and spaces in indentation
Also you can't use python 3.
Python 3 completely disallows indentation styles that use a mix of tabs and spaces.
PEP 373
End Of Life for Python 2.7: 2020
But that shouldn't be a problem because you never really have to upgrade to Python 3.
You can use Python 2 forever.