liveBook · Manning

Function extraction

As explained in Practices of the Python Pro

Function extraction is a refactoring technique that moves a coherent block of code into a separately named function.

Function extraction moves a coherent block of code into a separately named function. The name clarifies behavior, reduces duplication, and makes each concern easier to understand independently. section 2.2.1 section 2.3

Clarity and separation matter more than immediate reuse. After extracting a function, generalize arguments when the code mixes a specific value with a reusable operation, then extract smaller responsibilities when one function still does too much. section 2.2.1 section 9.2.2

A practical extraction sequence:

  • Identify a coherent block and give its behavior a clear name. section 2.2.1
  • Move the block into a function with the values it needs as parameters. section 2.2.1
  • Separate fixed details from general behavior by extracting them into arguments. section 2.2.1
  • Extract further functions when decision-making and implementation details grow together. section 9.2.2
  • Preserve the function’s inputs and expected behavior while improving its body. section 2.2.1

From a specific introduction to a reusable one

Instead of duplicating a loop for different lineups, define introduce(title, names). The same function can introduce the Three Stooges, the Teenage Mutant Ninja Turtles, or the Chipmunks. A second extraction, join_names(names), can isolate name-list formatting from the group introduction. section 2.2.1

Extraction in application code

A random-food endpoint can map response formats to functions such as to_json and to_xml, then delegate format selection to get_format_function. Each function has a smaller responsibility and lower cyclomatic complexity. section 9.2.2

def introduce_stooges(names):                 #1
    message = 'The Three Stooges: '
    for index, name in enumerate(names):
        if index > 0:
            message += ', '
        if index == len(names) - 1:
            message += 'and '
        message += name
    print(message)


introduce_stooges(['Moe', 'Larry', 'Shemp'])  #2
introduce_stooges(['Larry', 'Curly', 'Moe'])

Compare duplicated introduction logic with a named introduce_stooges function and its reusable calls. section 2.2.1

Listing 2.2. Code with extracted functions
import random

OPTIONS = ['rock', 'paper', 'scissors']


def get_computer_choice():
    return random.choice(OPTIONS)


def get_human_choice():
    choice_number = int(input('Enter the number of your choice: '))
    return OPTIONS[choice_number - 1]


def print_options():
    print('\n'.join(f'({i}) {option.title()}' for i,
 option in enumerate(OPTIONS)))


def print_choices(human_choice, computer_choice):
    print(f'You chose {human_choice}')
    print(f'The computer chose {computer_choice}')


def print_win_lose(human_choice, computer_choice, human_beats,
 human_loses_to):
    if computer_choice == human_loses_to:
        print(f'Sorry, {computer_choice} beats {human_choice}')
    elif computer_choice == human_beats:
        print(f'Yes, {human_choice} beats {computer_choice}!')


def print_result(human_choice, computer_choice):
    if human_choice == computer_choice:
        print('Draw!')
    if human_choice == 'rock':
        print_win_lose('rock', computer_choice, 'scissors', 'paper')
    elif human_choice == 'paper':
        print_win_lose('paper', computer_choice, 'rock', 'scissors')
    elif human_choice == 'scissors':
        print_win_lose('scissors', computer_choice, 'paper', 'rock')


print_options()
human_choice = get_human_choice()
computer_choice = get_computer_choice()
print_choices(human_choice, computer_choice)
print_result(human_choice, computer_choice)

See a large procedural rock-paper-scissors flow divided into functions for choices, options, output, and results. section 2.2.1

How Practices of the Python Pro covers it

How deep it goes
Explains named functions, generalized parameters, and concern splitting; it stops short of formal refactoring mechanics.
Examples
Uses fan-site introductions, rock-paper-scissors, response formatting, and Book title construction as extraction examples.
What you can do after
Apply it via Python functions to reduce duplication, name behavior, separate concerns, and extend response formats through mappings.
How it connects
Connects function extraction to separation of concerns, decomposition, reuse, cyclomatic complexity, methods, and extensibility.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Practices of the Python Pro. The section links point to the parts of the book it draws on.