Python for Network Engineers
Functions & Reusable Automation Logic
What you'll learn
- Why repeating the same logic in multiple places is a problem worth avoiding
- How def, parameters, and return work together to define a function
- How to call the same function on different devices
- The difference between defining a function once and reusing it many times
- How to recognize whether a piece of logic deserves to become a function
Listen to a guided explanation of this lesson.
Spoken narration isn't supported in this browser.
The problem functions solve
Picture checking NTP sync for three different devices, without functions — the same handful of lines, typed out three separate times, once per device, each with a slightly different variable name. It works. It's also exactly the kind of repetition this entire curriculum has been arguing against since "Start Here": the same logic, copy-pasted, is fragile — fix a bug in one copy and the other two still have it.
A function is how Python lets you package a repeatable task into a named, reusable block: define the logic once, then reuse it as many times as you need, for as many devices as you have.
- Check SW1NTP logic written out in full
- Check SW2same NTP logic, copy-pasted
- Check SW3same NTP logic, copy-pasted again
- def check_ntp(device):logic defined once
- check_ntp(SW1)
- check_ntp(SW2)
- check_ntp(SW3)
def, parameters, and return
def check_ntp(device):
if device["ntp_synced"]:
return "synced"
else:
return "out of sync"def starts a function definition; check_ntp is its name. (device) in parentheses is a parameter — a placeholder for whatever value gets passed in when the function is called. return hands a value back to whatever called the function, and immediately ends the function.
Three pieces, worth naming individually:
def check_ntp(device):— defines a function namedcheck_ntpthat expects one input, calleddeviceinside the function.device(the parameter) — a placeholder name. It doesn't refer to any specific device until the function is actually called with one.return "synced"— sends a value back out of the function, so whatever called it can use the result.
Calling the function
Defining a function doesn't run it — you have to call it, passing in an actual value for the parameter:
devices = [
{"hostname": "SW1", "ntp_synced": True},
{"hostname": "SW2", "ntp_synced": False},
]
for device in devices:
result = check_ntp(device)
print(f"{device['hostname']}: {result}")Each time through the loop, check_ntp(device) calls the function with the current device's dictionary. Inside the function, the parameter 'device' now refers to whichever dictionary was passed in. Output: SW1: synced, then SW2: out of sync — same function, two different results, because the input was different each time.
This is the payoff: check_ntp was defined exactly once, but it's being reused for every device in the loop, each time acting on that device's own data. Same shape as combining a loop with a condition, one lesson ago — a loop repeats; a function packages what gets repeated so it can be reused anywhere, not just inside this one loop.
Which function is actually reusable?
Not every function is equally reusable — it depends on whether it relies on a parameter, or on a value baked into the code:
# Not reusable — hardcoded to one device
def check_sw1_ntp():
device = {"hostname": "SW1", "ntp_synced": True}
return "synced" if device["ntp_synced"] else "out of sync"
# Reusable — works for any device passed in
def check_ntp(device):
return "synced" if device["ntp_synced"] else "out of sync"check_sw1_ntp only ever checks one hardcoded device — calling it twice gives the same result twice, no matter what. check_ntp takes device as a parameter, so calling it with a different dictionary each time produces a different, correct result for that device. Only the second one is genuinely reusable.
Not Netmiko yet
check_ntp here doesn't actually connect to anything — it just looks at a value already sitting in a dictionary. That's deliberate: this lesson is about the function concept, not about SSH sessions. A later module (Netmiko Fundamentals) is where a function like this starts actually talking to a real device.
Key takeaways
- A function packages a repeatable task into a named, reusable block — defined once with def, used as many times as needed.
- Parameters are placeholder names for whatever value gets passed in when the function is called; they have no value until then.
- return sends a value back out of a function, so the caller can use the result.
- A function that takes its input as a parameter is genuinely reusable across every device; one with a hardcoded value inside it isn't.
- Functions and loops solve related but different problems: a loop repeats an action; a function packages the action so it can be reused anywhere, not just inside one loop.