In the last post, we focused on Java and how to evaluate code review skills across different levels of engineering experience. In this post, we shift gears to Python, a language known for its simplicity—and sometimes the unintended complexity that follows.
This post includes:
- A Python code review style guide to share with candidates
- Three code review examples (junior, mid, and senior)
- Key things for interviewers to evaluate beyond syntax
Why Code Reviews in Python Interviews Matter
Python is deceptively simple. Bad code often works, until it scales or needs to be maintained. A good Python developer:
- Writes readable, idiomatic code
- Avoids hidden performance issues
- Uses standard libraries effectively
- Knows the tradeoffs of dynamic typing
Python Style Guide for Code Review Exercises
This style guide should be shared with interviewees at the beginning of the exercise:
✅ Code Style & Structure
- Follow PEP 8 for naming, spacing, and line length
- Use meaningful variable/function names
- Avoid deep nesting and large functions
🔒 Error Handling
- Use specific exceptions
- Avoid bare
except:
blocks - Log or re-raise errors when appropriate
📦 Code Organization
- Separate logic from I/O
- Avoid hardcoded values
- Minimize global state
🧪 Testability
- Use functions with clear input/output
- Write code that can be unit tested easily
🧼 Clean Code
- Remove unused imports/variables
- Prefer list comprehensions over manual loops (when readable)
- Use built-in functions where appropriate
Junior-Level Code Review Example
Code Snippet:
def process_data(data_list):
for item in data_list:
if "@" in item:
print("Email:", item)
else:
try:
num = int(item)
print("Number:", num * 2)
except:
print("Other:", item)
Issues to Spot:
- Bare
except
block (catches everything) - No input validation
- Uses print statements instead of return/log
- Function is not reusable/testable
Follow-up Prompt:
Refactor this into smaller functions. Replace print with return values or logging. Improve exception handling.
Mid-Level Code Review Example
Code Snippet:
import json
def save_user_info(user_id, data):
file_name = "user_" + str(user_id) + ".json"
with open(file_name, "w") as f:
f.write(json.dumps(data))
Issues to Spot:
- No error handling for file I/O
- Could use
json.dump()
instead ofwrite(json.dumps(...))
- Filename construction could be unsafe (injection risk)
- No file existence or overwrite handling
Follow-up Prompt:
Refactor with exception handling and safer filename logic. How would you make this testable and secure?
Senior-Level Code Review Example
Code Snippet:
class ReportGenerator:
def __init__(self, db):
self.db = db
def generate(self, report_type):
users = self.db.query("SELECT * FROM users")
if report_type == "summary":
return self._summarize(users)
elif report_type == "full":
return self._generate_full_report(users)
else:
print("Invalid report type")
def _summarize(self, users):
return {"total": len(users)}
def _generate_full_report(self, users):
return users
Issues to Spot:
- No input validation or report_type enforcement
- Logic for DB query is tightly coupled
-
print()
for error, instead of raising/logging - No logging or observability hooks
- Could use
Enum
or constants forreport_type
Follow-up Prompt:
How would you improve separation of concerns here? How would you test the report logic without a real DB?
Interviewer Tips
- Use open-ended prompts: "What assumptions did you make?", "Would this scale?", "How would you test this?"
- Look at how they reason through refactoring — not just what they fix
- Focus on communication, understanding of tradeoffs, and clarity of explanation
What’s Next
In the next posts, we’ll dive into JavaScript, Go, and other languages to show how to scale this model across stacks and seniority.
This series is about designing interviews that feel like working with a great teammate — not jumping through academic hoops.
Top comments (0)