Get network interfaces on Linux I wrote this in order to get a list of network interfaces on Linux. In the past, I have used publicly available methods from, say, ActiveState, which uses ioctl and was annoying to get working under Python 3. This version simply uses regular expressions on the output of ifconfig.

The documentation style used here follows the numpy documentation guide.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Get a list of network interfaces on Linux.

This code is compatible with Python versions 2 and 3.

"""
from collections import namedtuple
import re
import subprocess


def get_interfaces(external=False, ip=False):
    """
    Get a list of network interfaces on Linux.

    To access the MAC address and/or the IP address, set the relevant keyword
    arguments to True.

    Parameters
    ----------
    external : bool, optional
        Only show external interfaces, and ignore virtual (e.g. loopback)
        devices, and return their MAC addresses.
    ip : bool, optional
        Only show interfaces which are UP and have an IP address, and return
        their IPv4 addresses.

    Returns
    -------
    interfaces
        list of str containing the interface name by default, or list of
        namedtuple containing `name`, `mac`, and `ip` as requested.

    Examples
    --------
    &gt;&gt;&gt; print(get_interfaces())
    ['eth0', 'lo', 'wlan0']
    &gt;&gt;&gt; print(get_interfaces(external=True))
    [Interface(name='eth0', mac='a0:b1:c2:d3:e4:f5'), Interface(name='wlan0', ma
    c='f5:e4:d3:c2:b1:a0')]
    &gt;&gt;&gt; print(get_interfaces(ip=True))
    [Interface(name='lo', ip='127.0.0.1'), Interface(name='wlan0', ip='192.168.1
    1.2')]
    &gt;&gt;&gt; print(get_interfaces(external=True, ip=True))
    [Interface(name='wlan0', mac='f5:e4:d3:c2:b1:a0', ip='192.168.11.2')]

    """
    name_pattern = "^(\w+)\s"
    mac_pattern = ".*?HWaddr[ ]([0-9A-Fa-f:]{17})" if external else ""
    ip_pattern = ".*?\n\s+inet[ ]addr:((?:\d+\.){3}\d+)" if ip else ""
    pattern = re.compile("".join((name_pattern, mac_pattern, ip_pattern)),
                         flags=re.MULTILINE)

    ifconfig = subprocess.check_output("ifconfig").decode()
    interfaces = pattern.findall(ifconfig)
    if external or ip:
        Interface = namedtuple("Interface", "name {mac} {ip}".format(
            mac="mac" if external else "",
            ip="ip" if ip else ""))
        return [Interface(*interface) for interface in interfaces]
    else:
        return interfaces


if __name__ == "__main__":
    interfaces = get_interfaces(external=True, ip=True)
    for interface in interfaces:
        print("{name}: {ip}".format(name=interface.name, ip=interface.ip))
That is a huge docstring, it's longer than the code itself. You should read Python's PEP about how to write good docstrings.

For a start a docstring shouldn't contain examples, you can put that as a  regular comment in the script if you want. And you don't need to be so detailed and explicit about the type and optional nature of your parameters. I would take some information out of your parameters and returns sections and just fold it back into your opening section. Docstrings should be relatively concise and mostly add context and explanation.

A user can easily see the default parameters get_interfaces(external=False, ip=False), which reveals that they're optional and booleans. All you need to explain is what setting them will affect.