16 Common Python Runtime Errors Beginners Find
The Python 3 keywords are: and, as, assert, break, class, continue, def, del, elif, else, except, False, finally, for, from, global, if, import, in, is, lambda, None, nonlocal, not, or, pass, raise, return, True, try, while, with, yield
13) Using an augmented assignment operator on a new variable. (Causes “NameError: name 'foobar' is not defined”)
Do not assume that variables start off with a value such as 0 or the blank string. A statement with an augmented operator like spam += 1 is equivalent to spam = spam + 1. This means that there must be a value in spam to begin with.
This error happens with code like this:
spam = 0
spam += 42
eggs += 42
14) Using a local variable (with the same name as a global variable) in a function before assigning the local variable. (Causes “UnboundLocalError: local variable 'foobar' referenced before assignment”)
Using a local variable in a function that has the same name as a global variable is tricky. The rule is: if a variable in a function is ever assigned something, it is always a local variable when used inside that function. Otherwise, it is the global variable inside that function.
This means you cannot use it as a global variable in the function before assigning it.
This error happens with code like this:
someVar = 42
def myFunction():
print(someVar)
someVar = 100
myFunction()
15) Trying to use range() to create a list of integers. (Causes “TypeError: 'range' object does not support item assignment”)
Sometimes you want a list of integer values in order, so range() seems like a good way to generate this list. However, you must remember that range() returns a “range object”, and not an actual list value.
This error happens with code like this:
spam = range(10)
spam[4] = -1
What you probably want to do is this:
spam = list(range(10))
spam[4] = -1
(Update: This works in Python 2, because Python 2′s range() does return a list value. However, trying to do this in Python 3 will result in the above error.)
16) There is no ++ increment or –- decrement operator. (Causes “SyntaxError: invalid syntax”)
If you come from a different programming language like C++, Java, or PHP, you may try to increment or decrement a variable with ++ or --. There are no such operators in Python.
This error happens with code like this:
spam = 0
spam++
What you want to do is this:
spam = 0
spam += 1
17) Update: As Luciano points out in the comments, it is also common to forget adding self as the first parameter for a method. (Causes “TypeError: myMethod() takes no arguments (1 given)”)
This error happens with code like this:
class Foo():
def myMethod():
print('Hello!')
a = Foo()
a.myMethod()
A short explanation of various error messages appears in Appendix D of the “Invent with Python” book.
Sam:
July 9th, 2012 at 11:45 am
Interesting – but I’m pretty sure number 15 is incorrect. This worked for me in python 2.7 and python 3.
Sam:
July 9th, 2012 at 11:47 am
Although… in python 3 I can’t iterate over “spam”
Frank:
July 9th, 2012 at 11:53 am
4 is very unpythonic actually – one should rather use
“for i in spam” instead of “for i in range(len(spam))”.
That’s way more obvious when reading it.
Radomir Dopieralski:
July 9th, 2012 at 12:04 pm
Argh, number 4 is just plain wrong. Why do you encourage people to do the ugly `for i in range(len(spam)):` and then `spam[i]` when `for animal in animals:` and then `animal` is better in every way, and also lets you avoid the opportunity of this error completely?
Radomir Dopieralski:
July 9th, 2012 at 12:06 pm
And if you need the index too for whatever reason, just use `enumerate()`.
Paul:
July 9th, 2012 at 6:30 pm
About number 3, mixing tabs and spaces is a common cause. That happens a lot to people that are learning: copy examples (which tend to use spaces) from a website but modify the code using an editor configured to use tabs.
Nick Coghlan:
July 9th, 2012 at 9:24 pm
As Radomir notes, the two idiomatic ways of looping over a container in modern Python are:
for x in container:
…
for i, x in enumerate(container):
…
The latter was added back in 2.3 specifically to replace the older idiom:
for i in range(len(container)):
x = container[i]
…
enumerate() has the benefit of work for arbitrary iterables, whereas the older idiom only worked for sequences.
However, passing a container when you meant to pass len(container) is still a good example of a potentially confusing error.
Nick Coghlan:
July 9th, 2012 at 9:28 pm
For item 6, rather than mod-style string formatting, I’d recommend the less quirky format method:
numEggs = 12
print(‘I have {} eggs.’.format(numEggs))
Nick Coghlan:
July 9th, 2012 at 9:32 pm
Final one: the 2.x equivalent of 15 occurs when using xrange() (it returns a custom iterator rather than a list object)
Good list of common errors :)
Luciano Pacheco:
July 10th, 2012 at 12:49 am
You forgot the forgetting of self in methods definition.
Danny:
July 10th, 2012 at 7:31 pm
I like this list a lot, especially as I think everyone forgets quite how much beginners are thrown by bland errors on stuff like tabs/spaces. I think it leads to a lot of the “mein gott! whitespace!” reactions that Python gets.
I wish Python error messages could be a bit more expansive in these cases, or perhaps IDEs could play that role.
Chris:
July 11th, 2012 at 5:18 am
Great list, I see these a lot when teaching Python. I find the error messages are really not good enough for those just starting to program. Sometimes they are too vague to be useful like giving “invalid syntax” for a host of different problems. Other times they are confusing to the beginner (what’s an EOL?)
Does anyone know how much work it would be to detect these common mistakes and offer clear, nontechnical explanations? I’d be willing to look at it if it’s not a huge undertaking.
Chris:
July 11th, 2012 at 3:02 pm
Another take on #10 where you noted the dangers of trying to call an item from a list where the index is out of range. You also can’t assign to an index out of range.
Trying to append to a list by index:
list = ['a','b','c']
list[3] = ‘d’
IndexError: list assignment index out of range
list = ['a','b','c']
list.append(‘d’)
antiloquax:
July 12th, 2012 at 12:51 am
Hi Al,I have just found your blog.I’m sure you’ve heard about the Raspberry Pi and it’s support for Python. I am one of the writers at the MagPi magazine. We like your books!
mark
http://www.themagpi.com/
wobsta:
July 12th, 2012 at 8:53 am
My favorite error is not in your list:
i = 0
print “number: %d” % i+1
results in
TypeError: cannot concatenate ‘str’ and ‘int’ objects
John Gill:
July 16th, 2012 at 8:04 am
Many of these errors are flagged by pyflakes. I have that set up to do the checking on the fly in emacs. It has significantly reduced the time I spend fixing run time errors.
ms4py:
July 19th, 2012 at 12:24 am
Please update number 4 again. There are a lot of comments how to do it right (with enumerate).
And add the one from wobsta (http://inventwithpython.com/blog/2012/07/09/16-common-python-runtime-errors/#comment-8730). This is my favorite, too.