Fundamentals 13 min read

13 Common Python Pitfalls Every Developer Should Avoid

This article explains the most frequent Python traps—such as mutable default arguments, subtle differences between x+=y and x=y+y, tuple syntax, list mutability, iteration pitfalls, closure binding, import quirks, version incompatibilities, and GIL—providing clear examples and practical solutions.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
13 Common Python Pitfalls Every Developer Should Avoid

Definition of a Trap

In my view, a trap is code that appears to work but not in the way you expect; if it raises an exception immediately, it is not a trap. For example, the UnboundLocalError many Python programmers encounter.

>> a=1
>>> def func():
...     a+=1
...     print a
>>> func()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in func
UnboundLocalError: local variable 'a' referenced before assignment

A more advanced version involves the random module:

import random

def func(ok):
    if ok:
        a = random.random()
    else:
        import random
        a = random.randint(1,10)
    return a

func(True)  # UnboundLocalError: local variable 'random' referenced before assignment

These errors are not traps because the code always fails, unlike subtle bugs that run incorrectly.

1. Mutable Objects as Default Arguments

Using a mutable object as a default parameter can lead to unexpected shared state.

>> def f(lst=[]):
...     lst.append(1)
...     return lst
>>> f()
[1]
>>> f()
[1, 1]

Default values are evaluated when the function is defined, not when called.

>> import time
>>> def report(when=time.time()):
...     return when
>>> report()
1500113234.487932
>>> report()
1500113234.487932

The recommended fix is to use None as the default and assign inside the function.

>> def report(when=None):
...     if when is None:
...         when = time.time()
...     return when
>>> report()
1500113446.746997
>>> report()
1500113448.552873

2. x += y vs x = x + y

These are usually equivalent, but with mutable objects they behave differently.

>> x=[1]; x+=[2]; print x
[1, 2]
>>> x=[1]; x = x+[2]; print x
[1, 2]
>>> x=[1]; print id(x); x=x+[2]; print id(x)
4357132800
4357132728
>>> x=[1]; print id(x); x+=[2]; print id(x)
4357132800
4357132800

The augmented assignment modifies the object in place, while the plain addition creates a new object.

3. The Magic of Parentheses

Parentheses create tuples, but a single element needs a trailing comma.

>> a = (1, 2)
>>> type(a)
<class 'tuple'>
>>> a = (1)
>>> type(a)
<class 'int'>
>>> a = (1,)
>>> type(a)
<class 'tuple'>

4. Creating a List of Lists

Using multiplication creates multiple references to the same inner list.

>> a = [[]] * 10
>>> a[0].append(10)
>>> a
[[10], [10], [10], [10], [10], [10], [10], [10], [10], [10]]

The correct way is a list comprehension.

>> a = [[] for _ in range(10)]
>>> a[0].append(10)
>>> a
[[10], [], [], [], [], [], [], [], [], []]

5. Modifying a List While Iterating

Removing elements during iteration can skip items because the index continues to increase.

def modify_lst(lst):
    for idx, elem in enumerate(lst):
        if elem % 3 == 0:
            del lst[idx]

Using list comprehensions or iterating over a copy avoids this issue.

6. Closures and lambda

Late binding in closures causes all lambdas to capture the same variable value.

>> def create_multipliers():
...     return [lambda x: i*x for i in range(5)]
>>> for m in create_multipliers():
...     print m(2)
8
8
8
8
8

Fix by binding the current value as a default argument.

>> def create_multipliers():
...     return [lambda x, i=i: i*x for i in range(5)]

7. The del Method and Circular References

Defining __del__ can prevent the garbage collector from collecting circular references, leading to memory leaks.

8. Different Import Styles for the Same Module

Importing a module inside functions can create distinct module objects, especially when manipulating sys.path.

def add(x):
    from mypackage import mymodule
    mymodule.l.append(x)
    print "updated list", mymodule.l, id(mymodule)

def get():
    import mymodule
    print "module in get", id(mymodule)
    return mymodule.l

Consistent import practices are essential in larger projects.

9. Python 2 vs Python 3 Differences

Key incompatibilities include range returning a list in 2.x versus a range object in 3.x, and functions like map, filter, dict.items() returning lists versus iterators.

10. ++i and --i

In Python these are parsed as two unary plus or minus operators, leaving the value unchanged.

11. setattr , getattr , __getattribute__

These magic methods control attribute access; setattr and __getattribute__ are counterparts, while getattr is only called when normal lookup fails.

12. The GIL

The Global Interpreter Lock is a well‑known limitation of CPython that can hinder multithreaded performance.

Conclusion

Python is easy to learn and powerful, but it contains many subtle traps. Understanding these pitfalls—such as mutable defaults, closure binding, import quirks, and version differences—helps developers write more reliable code. This list is not exhaustive; contributions are welcome.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Pythonprogrammingbugsbest-practicesclosuresPitfallsmutable-defaults
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.