Using namedtuple as a poorman's parser

John Paul Janecek bio photo By John Paul Janecek

I needed to parse the routing tables, therefore I needed to parse the command route which gives an output similar to something like this.

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.17.0.1      0.0.0.0         UG    0      0        0 eth0
172.17.0.0      *               255.255.0.0     U     0      0        0 eth0

To get the output of the command we will use subprocess. So our python code will look like this.

import subprocess

p = subprocess.run("route",stdout = subprocess.PIPE)
lines = p.stdout.decode("utf8").splitlines()
headers = lines[1].split()

But how to create a nice datastructure to hold routes ? The answer is namedtuple.

Route = namedtuple("Route",headers)
routes = [Route(*line.split()) for line in lines[2:]]

route = routes[0]
print(route)
print("as a tuple %s" % route[0])
print("as a class like structure" % route.Destination)
print("as a dictionary %s" % route._asdict())

The output is.

Route(Destination='default', Gateway='172.17.0.1', Genmask='0.0.0.0', Flags='UG', Metric='0', Ref='0', Use='0', Iface='eth0')
as a tuple : default
as a class like structure : default
as a dictionary : OrderedDict([('Destination', 'default'), ('Gateway', '172.17.0.1'), ('Genmask', '0.0.0.0'), ('Flags', 'UG'), ('Metric', '0'), ('Ref', '0'), ('Use', '0'), ('Iface', 'eth0')])

The flexibility of python never ceases to amaze me, and I am always finding hidden gems and quicker ways to do things.