Common Python Pitfalls: Dynamic Typing, Mutable Default Arguments, Scope, and List Modification
This article examines several confusing behaviors in Python—including implicit variable declarations, mutable default arguments, class variable inheritance, scope rules, and list‑modification during iteration—illustrating each with code examples and offering practical solutions for developers.
Python has become the most popular language for data science and AI, but it still contains many confusing behaviors that can trip up both beginners and experienced developers.
Because Python is dynamically typed, variables are created without explicit type declarations, which can lead to runtime crashes when a variable’s type is not what the code expects.
Mutable default arguments are a classic source of bugs; the function def add_five(a, b=0): return a + b + 5 works as expected, but using a mutable object like a list as a default value causes the list to retain items across calls, as shown by the add_element examples that unexpectedly return ["foo", "foo"] on the second call.
<code>def add_five(a, b=0):
return a + b + 5</code> <code>add_five(3) # returns 8
add_five(3, 4) # returns 12</code> <code>def add_element(lst=[]):
lst.append("foo")
return lst
add_element() # returns ["foo"]
add_element() # returns ["foo", "foo"] # unexpected</code>Class variables are shared across all instances unless overridden; modifying a subclass’s attribute does not affect the parent, but changing the parent’s attribute propagates to subclasses, which can be surprising.
<code>class Parent(object):
x = 1
class FirstChild(Parent):
pass
class SecondChild(Parent):
pass
print(Parent.x, FirstChild.x, SecondChild.x) # 1 1 1
FirstChild.x = 2
print(Parent.x, FirstChild.x, SecondChild.x) # 1 2 1
Parent.x = 3
print(Parent.x, FirstChild.x, SecondChild.x) # 3 2 3</code>Scope rules can also be confusing: a variable defined inside a function is not accessible outside, and attempting to modify a global variable without the global keyword raises UnboundLocalError . Declaring the variable as global resolves the issue.
<code>x = 2
def add_5():
global x
x = x + 5
print(x)
add_5() # works, prints 7</code>Modifying a list while iterating over it leads to index errors; a safer approach is to use a list comprehension that filters out unwanted elements in a single expression.
<code>mynumbers = [x for x in range(10) if x % 3 != 0]
# Result: [1, 2, 4, 5, 7, 8]</code>Although Python’s execution speed has historically been slower than compiled languages, modern libraries such as NumPy, and multi‑core processing, as well as the rise of machine‑learning frameworks like PyTorch and TensorFlow, have mitigated many performance concerns. Nonetheless, developers should remain aware of these language quirks when writing robust Python code.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.