Engineering Craft › Refactoring
Extract Function
Pulling a block of code into a well-named function.
Also known as: extract method, extract function refactoring
Extract function is a refactoring where you take a block of code, move it into a new function, and replace the original with a call. It’s the most used refactoring there is, and the standard cure for long methods.
Before:
def print_invoice(order):
total = 0
for item in order.items:
total += item.price * item.qty
if order.customer.is_member:
total *= 0.9
print(f"{order.customer.name}: {total}")
After:
def calculate_total(order):
total = sum(i.price * i.qty for i in order.items)
return total * 0.9 if order.customer.is_member else total
def print_invoice(order):
print(f"{order.customer.name}: {calculate_total(order)}")
When to do it
- A block needs a comment to explain it: turn the comment into a function name.
- A function does several things.
- The same code appears in two places (DRY).
- Deeply nested code could use a named inner step (deep nesting).
How to do it safely
- Make sure you have tests (or write a quick one) (refactoring).
- Select the block and use your editor’s extract function command (IDE refactoring tools). It figures out parameters and return values.
- Name it for what it does, not how (naming):
calculate_total, notloop_items. - Run the tests.
By hand, check what the block reads (it becomes parameters) and what it changes (it becomes return values).
Pitfalls
- Too many parameters. If the new function needs six arguments, the extraction cut across a boundary. Consider extracting a class or grouping values (introduce parameter object).
- Meaningless names like
part2. - Tiny functions that each need the others’ details can scatter the logic.
- Behavior changes. Extraction should not change what the code does.