Stop Writing Messy Code – Master Python Functions Now

Learn what Python functions are, explore their types, and see practical examples to write clean, reusable, and efficient code.


Cisco DevNet Associate course 013 Software Development and Design Explain the benefits of organizing code into methods / functions

Watch Full Demo on YouTube:

Introduction:

In Python, functions are one of the most important building blocks for creating clean, efficient, and reusable code. They allow you to group related code into a single, reusable unit, making your programs more organized and easier to maintain. Whether you are working on a small script or a large-scale application, understanding how functions work — and the different types you can use — is essential for writing professional Python code.


💡 What is a Function in Python?

A function in Python is a reusable block of code designed to perform a specific task. Instead of writing the same instructions multiple times, you can define a function once and call it whenever needed. This helps avoid repetition, reduces errors, and makes code easier to read.

Functions can take parameters (inputs), perform operations, and optionally return a result (output). They are defined using the def keyword followed by a name, parameters in parentheses, and a block of indented code.

Basic Python Function

Let’s start with a simple example:

def greet(name):
    """Return a greeting message for the given name."""
    message = "Hello, " + name + "!"
    return message

# Calling the function
print(greet("Amina"))
print(greet("Sarah"))

Step-by-step breakdown:

  1. def greet(name): – We use the def keyword to define a new function called greet that takes one parameter, name.
  2. message = "Hello, " + name + "!" – Inside the function, we create a message by combining text with the value passed in name.
  3. return message – The function sends the greeting back to the caller.
  4. Function calls – We call greet("Amina") and greet("Sarah"), printing the returned greetings.

Output:

Hello, Amina!
Hello, Sarah!

📊 Types of Functions in Python

Python offers several types of functions, each serving different purposes:

1. Built-in Functions

Functions that come pre-installed with Python, such as:

  • print() – Displays output.
  • len() – Returns the length of a sequence.
  • type() – Shows the data type of a value.

Example:

ips = ["10.0.0.1", "10.0.0.2"]
print("Count:", len(ips))
print("First type:", type(ips[0]))

2. User-Defined Functions

Functions that you create yourself to perform specific tasks.
Example:

def get_device_info(hostname, ip, platform='cisco_ios'):
    return {'hostname': hostname, 'ip': ip, 'platform': platform}

device = get_device_info('core-switch', '10.10.10.1')
print(device)

This is how you package domain logic (e.g., building device records) so it’s reusable and testable.


3. Lambda Functions

One-line, unnamed functions made with lambda, useful for short operations passed into higher-level functions.
Example:

interfaces = ['Gig0/12', 'Gig0/1', 'Gig0/2']
interfaces.sort(key=lambda s: int(s.split('/')[-1]))
print(interfaces)

The lambda converts the string Gig0/12 to the integer 12 for numerical sorting. Lambdas are great for sort, map, filter.

Caveat: Keep them short — for complex logic use a regular function.


4. Recursive Functions

Functions that call themselves to solve problems that can be broken down into smaller versions of the same problem.
Example:

def factorial(n):
    if n == 0:
        return 1
    return n * factorial(n - 1)

print(factorial(5))  # Output: 120

Recursion is elegant for tree traversals or divide-and-conquer algorithms. Always ensure there’s a base case to prevent infinite recursion.


5. Generator Functions

Functions that use yield to produce a sequence of values lazily, one at a time, saving memory
Example:

def interface_generator(prefix, count):
    for i in range(1, count+1):
        yield f"{prefix}{i}"

for iface in interface_generator("Gig0/", 5):
    print("Configuring", iface)

Instead of creating a full list of interface names, the generator yields each one when needed. This matters when handling large data streams (device lists, logs).


6. Nested Functions

Functions defined inside other functions, used for encapsulation and closure usage.
Example:

def configure_vlan(device_ip):
    def connect():
        print(f"Connecting to {device_ip}")
        return True
    def apply(vlan, name):
        print(f"Applying VLAN {vlan} ({name})")
    if connect():
        apply(10, "MGMT")
configure_vlan("192.168.1.1")

Nested functions help keep helper logic private to the outer function and can capture variables from the outer scope (device_ip) — that’s a closure.


7. Higher-order Functions (Decorators included)

Functions that accept other functions as arguments or return functions. Python decorators are a common pattern built on this.
Example:

def log_operation(fn):
    def wrapper(*args, **kwargs):
        print(f"Calling {fn.__name__} with {args} {kwargs}")
        return fn(*args, **kwargs)
    return wrapper

@log_operation
def backup_config(device):
    print("Backing up", device)

backup_config("sw1")

The log_operation function returns wrapper, a new function that adds logging around backup_config. Higher-order functions let you add behaviour (logging, retry, caching) without modifying the original function.


8. Class Methods and Static Methods

Methods inside classes that operate on the class (@classmethod) or are utility functions related to the class (@staticmethod). Instance methods operate on objects.
Example:

class NetworkDevice:
    def __init__(self, hostname, ip):
        self.hostname = hostname
        self.ip = ip
    
    def ping(self, target):
        """Instance method to ping from this device"""
        print(f"Pinging {target} from {self.hostname} ({self.ip})")
        return True
    
    @classmethod
    def from_csv(cls, csv_string):
        """Alternative constructor from CSV"""
        hostname, ip = csv_string.split(',')
        return cls(hostname, ip)
    
    @staticmethod
    def validate_ip(ip):
        """Static method to validate IP"""
        parts = ip.split('.')
        return len(parts) == 4 and all(0 <= int(p) <= 255 for p in parts)

# Usage
device1 = NetworkDevice('router1', '192.168.1.1')
device1.ping('8.8.8.8')

from_csv is an alternative constructor; validate_ip is a utility that logically groups with NetworkDevice. Class methods are important for alternate construction patterns and class-level operations.


9. Coroutine Functions (async/await)

Asynchronous functions defined with async def that use await to pause for I/O without blocking the entire program. Great for concurrent network I/O.
Example:

import asyncio

async def check(device):
    print("Checking", device)
    await asyncio.sleep(1)  # non-blocking
    print(device, "OK")

async def main():
    await asyncio.gather(*(check(d) for d in ["r1","sw1","fw1"]))

asyncio.run(main())

All three checks run concurrently (not serially), making async ideal for many simultaneous network requests.

When to prefer: High-latency I/O tasks: SSH sessions, HTTP API polling, SNMP queries done at scale.


10. Partial Functions (functools.partial)

Functions created by pre-filling some arguments of an existing function using partial, producing convenience wrappers.
Example:

from functools import partial

def configure(device, interface, config):
    print(device, interface, config)

cfg_g0_1 = partial(configure, "router1", "Gig0/1")
cfg_g0_1("description uplink")

cfg_g0_1 is now a simplified function that already knows the device and interface; you only pass the config.

When to prefer: When you repeatedly call a function with the same args — partials reduce duplication and make code simpler.


🧾 Conclusion

Functions are the backbone of well-structured Python code. They allow you to break complex problems into smaller, reusable chunks, making your programs easier to understand, maintain, and expand. By mastering both built-in and user-defined functions — as well as specialized types like lambdas, recursion, and class methods — you’ll be equipped to write more efficient and professional Python applications.

References:

DevNet Associate – Cisco

Cisco Certified DevNet Expert (v1.0) Equipment and Software List

DevNet Associate Exam Topics


Discover more from IEE

Subscribe to get the latest posts sent to your email.


Discover more from IEE

Subscribe now to keep reading and get access to the full archive.

Continue reading