Форум сайта python.su
0
Здравствуйте. Помогите советами по задаче. Как лучше решить?
задача:
Соответствие типа мака, его формату записи:
0: AA-BB-CC-DD-EE-FF
1: AA:BB:CC: DD:EE:FF
2: AABB.CCDD.EEFF
3: AABBCCDDEEFF
Необходимо написать класс Mac, при создании экземпляра класса, на вход подаётся аргумент характеризующий мак адрес, если аргумент является строкой и соответствует одному из форматов маков то создаём экземпляр класса. Если не строка или строка не того формата, нужно выкинуть исключения.
Проверка, что строка соответствует одному из форматов мака должно осуществляться посредством регулярных выражений.
Также у класса есть атрибут type - означающий в каком формате будет отображаться мак при преобразовании в строку экземпляра класса, значение по умолчанию 0.
Метод set_type собственно задаёт атрибут type, само собой проверяются входящие значения на валидность.
Должна быть функция __str__ вызываемая при преобразовании объекта в строку, она принимает в расчёт значение атрибута type.
Также нужно определить функцию __eq__, дабы выполнялось условие:
Mac('AA-BB-CC-DD-EE-FF') == Mac('AABB.CCDD.EEFF') # True
Mac('AA-BB-CC-DD-EE-FF') == 1 # False
Использовать декоратор total_ordering, для организации сравнения двух
экземпляров класс Mac
Сгенерировать список маков
macs =
И отсортировать его
Отредактировано MSunov (Март 3, 2016 18:32:21)
Офлайн
0
Пока есть только вот такой код.
import re class Mac: def __init__(self, mac, mac_type = 0): self._mac = mac self._type = mac_type # def set_type(self): # if self._mac == r'\w*' and self._type == r'[0-3]' and len(self._mac) == 12: # print(mac) # else: # print('Error') def __str__(self): if self._type == 0: s = re.sub(r'(\w\w)(\w\w)(\w\w)(\w\w)(\w\w)(\w\w)', r'\1-\2-\3-\4-\5-\6', self._mac) elif self._type == 1: s = re.sub(r'(\w\w)(\w\w)(\w\w)(\w\w)(\w\w)(\w\w)', r'\1:\2:\3:\4:\5:\6', self._mac) elif self._type == 2: s = re.sub(r'(\w\w\w\w)(\w\w\w\w)(\w\w\w\w)', r'\1.\2.\3', self._mac) return s def __eq__(self, other): pass print(Mac('AABBCCDDEEFF', 2))
Офлайн
253
MSunov1 хранить мак как число или список а не как строку. Главное чтобы оно было стандартизировано, чтобы проще было форматировать и сравнивать.
Как лучше решить?
r'(\w\w)(\w\w)(\w\w)(\w\w)(\w\w)(\w\w)'
>>> re.match(r"([0-9A-Fa-f]{2})"+"-([0-9A-Fa-f]{2})"*5,"AA-BB-CC-DD-EE-F0").groups() ('AA', 'BB', 'CC', 'DD', 'EE', 'F0')
Офлайн
0
MSunov
Проверка, что строка соответствует одному из форматов мака должно осуществляться посредством регулярных выражений.
Офлайн
0
Вот еще чуть добавил. Помогите пож-та доработать.
import re class Mac: def __init__(self, mac, mac_type = 0): self._mac = str(mac).lower() self._type = mac_type def set_type(self): if (self._mac == r'\w*') and (self._type == r'[0-3]') and (len(self._mac) == 12): pass else: print('Error') def __str__(self): self.standart = re.sub(r'\W*', '', self._mac) try: if (self._type == 0) and (len(self.standart) == 12): s = re.sub(r'(\w\w)(\w\w)(\w\w)(\w\w)(\w\w)(\w\w)', r'\1-\2-\3-\4-\5-\6', self.standart) elif (self._type == 1) and (len(self.standart) == 12): s = re.sub(r'(\w\w)(\w\w)(\w\w)(\w\w)(\w\w)(\w\w)', r'\1:\2:\3:\4:\5:\6', self.standart) elif (self._type == 2) and (len(self.standart) == 12): s = re.sub(r'(\w\w\w\w)(\w\w\w\w)(\w\w\w\w)', r'\1.\2.\3', self.standart) elif (self._type == 3) and (len(self.standart) == 12): s = self.standart except Exception as ex: print("ОШИБКА:", ex) return s def __eq__(self, other): self.other = re.sub(r'\W*', '', str(other).lower()) self.standart = re.sub(r'\W*', '', self._mac) if self.other == self.standart: return True else: return False print(Mac('AABBCCDDEEFF') == Mac('AA-BB-CC-DD-EE-Fd'))
Офлайн
857
>>> import re >>> >>> class Mac: ... ... def __init__(self, s): ... typ, val = self._parse_string(s) ... if not 0 <= typ <= 4: ... raise ValueError('Unknown format "{}"'.format(s)) ... self._addr_type = typ ... self._addr_value = val ... self._str_type = 0 ... ... def _parse_string(self, s): ... regexps = ( ... r'^([A-F0-9]{2})-([A-F0-9]{2})-([A-F0-9]{2})' ... r'-([A-F0-9]{2})-([A-F0-9]{2})-([A-F0-9]{2})$', ... ... r'^([A-F0-9]{2}):([A-F0-9]{2}):([A-F0-9]{2})' ... r':([A-F0-9]{2}):([A-F0-9]{2}):([A-F0-9]{2})$', ... ... r'^([A-F0-9]{2})([A-F0-9]{2})\.([A-F0-9]{2})' ... r'([A-F0-9]{2})\.([A-F0-9]{2})([A-F0-9]{2})$', ... ... r'^([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})' ... r'([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})$', ... ) ... for i, pat in enumerate(regexps): ... m = re.search(pat, s) ... if m is not None: ... return i, bytes([int(i, 16) for i in m.groups()]) ... return -1, b'' ... ... def __str__(self): ... formats = ( ... '{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}', ... '{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}', ... '{:02X}{:02X}.{:02X}{:02X}.{:02X}{:02X}', ... '{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}' ... ) ... return formats[self._str_type].format(*self._addr_value) ... ... def set_type(self, v): ... if not 0 <= v <= 4: ... raise ValueError('Unknown type "{}"'.format(v)) ... self._str_type = v ... ... def __eq__(self, v): ... return \ ... isinstance(v, self.__class__) and \ ... v._addr_value == self._addr_value ... >>> >>> m = Mac('AA-BB') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in __init__ ValueError: Unknown format "AA-BB" >>> >>> m = Mac('AA-BB-CC-11-22-33') >>> str(m) 'AA-BB-CC-11-22-33' >>> m.set_type(2) >>> str(m) 'AABB.CC11.2233' >>> >>> Mac('AA-BB-CC-DD-EE-FF') == Mac('AABB.CCDD.EEFF') True >>> Mac('AA-BB-CC-DD-EE-FF') == 1 False >>>
Офлайн