Anatomy of a Python Function

A straightforward, nerdy explanation of how to use functions in Python. You'll learn how to write a function and its importance for cleaner code.

Anatomy of a Python Function
Photo by Chris Ried / Unsplash

A while back, I thought it’d be fun to build a little d20 rolling app.
Simple enough, right? Push a button → roll a twenty-sided die → get a random result between 1 and 20.

But when I sat down to write the logic, I realized something: this “roll a die” action is a specific set of steps I’ll want to use over and over again. Not just once, not just for d20s, but for any dice size.

That’s where functions come in.

A function in Python is like giving a name to a move you know you’ll repeat. Instead of rewriting the steps every single time, you package them into one reusable piece of code — then just call it whenever you need it.

Let’s look at what that means in practice.


Defining a Function (Rolling Dice Edition)

Here’s how I might write a function to roll a d20:

import random

def roll_d20():
    return random.randint(1, 20)

Now every time I want to roll the die, I don’t rewrite the logic. I just call:

print(roll_d20())

Run it again → different result. Just like throwing a physical die on the table.

This is the heart of a function: define once, use anywhere.


Parameters and Arguments (Custom Dice)

Of course, we don’t just roll d20s. Sometimes you need a d6 for damage, or a d8 for hit dice. Hardcoding 20 into the function isn’t very flexible.

Let’s make it reusable:

def roll_die(sides=20):
    return random.randint(1, sides)

Now:

roll_die()      # Defaults to 20 sides
roll_die(6)     # Rolls a d6
roll_die(8)     # Rolls a d8

Here’s the difference:

  • sides is the parameter — the placeholder name inside the function.
  • 20, 6, or 8 are the arguments — the actual values you pass when calling it.

What Does return Do in Python?

When we roll a die, we want the result back. That’s what return is for.

Without return, the function just does something internally and then disappears. With return, it hands us the result so we can use it later.

Compare these two:

def roll_and_print():
    print(random.randint(1, 20))

def roll_and_return():
    return random.randint(1, 20)
  • roll_and_print() shows the result in the console, but that’s it.
  • roll_and_return() actually gives us the number back.
result = roll_and_return()
if result == 20:
    print("Critical hit!")

That’s the power of return. It makes your functions produce values you can build on, instead of just shouting into the void.


Scope and Lifetime of Variables

Another thing to know: variables created inside a function stay inside that function.

def roll_die(sides=20):
    result = random.randint(1, sides)
    return result

result only exists within roll_die. Outside of it, Python has no idea what you’re talking about. That’s a good thing — it keeps functions self-contained, like spells that only last as long as they’re being cast.


Putting It All Together: is_even() Example

Not everything has to be dice rolls. Here’s a tiny utility function:

def is_even(number):
    if number % 2 == 0:
        return True
    return False
  • Call is_even(4) → returns True.
  • Call is_even(5) → returns False.

Simple, but powerful. You’ll find yourself writing dozens of these helpers once you get comfortable with functions.


Best Practices for Functions

A few battle-tested lessons from writing production Python:

  • One job per function. Don’t cram three different tasks together.
  • Name them clearly. roll_die() is obvious; doStuff() is useless.
  • Use defaults smartly. Like defaulting to 20 sides in our dice roller.
  • Return results, don’t print. Printing is fine for debugging, but returning values gives your code actual flexibility.

Conclusion

For me, the “aha” moment with functions wasn’t some academic definition — it was building something nerdy I actually cared about, like a dice roller. Suddenly I saw functions not as “syntax to memorize,” but as the way to package repeatable logic into neat little spells I could cast anywhere in my code.

So next time you ask yourself “what does return do in Python?”, remember the d20 function. Without return, the die roll would vanish into the void. With return, you can keep that critical hit in your hands, ready to use.

Go build your own little utilities. Wrap them in functions. And watch how much cleaner your code feels once you start thinking this way.