Пример использования генератора для обработки вывода sh cdp neighbors detail#

Генераторы могут использоваться не только в том случае, когда надо возвращать элементы по одному.

Например, генератор get_cdp_neighbor читает файл с выводом sh cdp neighbor detail и выдает вывод частями, по одному соседу:

def get_one_neighbor(filename):
    with open(filename) as f:
        line = ''
        while True:
            while not 'Device ID' in line:
                line = f.readline()
            neighbor = line
            for line in f:
                if '----------' in line:
                    break
                neighbor += line
            yield neighbor
            line = f.readline()
            if not line:
                return

Полный скрипт выглядит таким образом (файл parse_cdp_neighbors.py):

import re
from pprint import pprint


def get_one_neighbor(filename):
    with open(filename) as f:
        line = ''
        while True:
            while not 'Device ID' in line:
                line = f.readline()
            neighbor = line
            for line in f:
                if '----------' in line:
                    break
                neighbor += line
            yield neighbor
            line = f.readline()
            if not line:
                return


def parse_neighbor(output):
    regex = (
        r'Device ID: (\S+).+?'
        r' IP address: (?P<ip>\S+).+?'
        r'Platform: (?P<platform>\S+ \S+), .+?'
        r', Version (?P<ios>\S+),')

    result = {}
    match = re.search(regex, output, re.DOTALL)
    if match:
        device = match.group(1)
        result[device] = match.groupdict()
    return result

if __name__ == "__main__":
    data = get_one_neighbor('sh_cdp_neighbors_detail.txt')
    for n in data:
        pprint(parse_neighbor(n), width=120)

Так как генератор get_cdp_neighbor выдает каждый раз вывод про одного соседа, можно проходиться по результату в цикле и передавать каждый вывод функции parse_cdp. И конечно же, полученный результат тоже можно не собирать в один большой словарь, а передавать куда-то дальше на обработку или запись.

Результат выполнения:

$ python parse_cdp_neighbors.py
{'SW2': {'ios': '12.2(55)SE9', 'ip': '10.1.1.2', 'platform': 'cisco WS-C2960-8TC-L'}}
{'R1': {'ios': '12.4(24)T1', 'ip': '10.1.1.1', 'platform': 'Cisco 3825'}}
{'R2': {'ios': '15.2(2)T1', 'ip': '10.2.2.2', 'platform': 'Cisco 2911'}}
{'R3': {'ios': '15.2(2)T1', 'ip': '10.3.3.3', 'platform': 'Cisco 2911'}}