# https://stepik.org/lesson/701985/step/10?unit=702086 class ValidateString: def __init__(self, min_length=0, max_length=1000): self.min_length, self.max_length = min_length, max_length def validate(self, value): return ( isinstance(value, str) and self.min_length <= len(value) <= self.max_length ) class StringValue: def __init__(self, validator=None): if validator is None: validator = ValidateString(min_length=3, max_length=100) self.validator = validator def __set_name__(self, owner, name): self.name = "_" + name def __get__(self, instance, owner): return getattr(instance, self.name) def __set__(self, instance, value): if self.validator.validate(value): setattr(instance, self.name, value) class RegisterForm: login = StringValue() password = StringValue(ValidateString(min_length=3, max_length=100)) email = StringValue() def __init__(self, login, password, email): self.login, self.password, self.email = login, password, email def get_fields(self): return [self.login, self.password, self.email] def show(self): print(f"
") for name, field in zip("Логин Пароль Email".split(), self.get_fields()): print(f"{name}: {field}") print(f"
") def tests(): assert hasattr( ValidateString, "validate" ), "в классе ValidateString отсутствует метод validate" r = RegisterForm("11111", "1111111", "11111111") assert ( hasattr(r, "login") and hasattr(r, "password") and hasattr(r, "email") ), "в классе RegisterForm должны быть дескрипторы login, password, email" assert hasattr(RegisterForm, "show"), "в классе RegisterForm отсутствует метод show" StringValue.__doc__ frm = RegisterForm("123", "2345", "sc_lib@list.ru") assert frm.get_fields() == [ "123", "2345", "sc_lib@list.ru", ], "метод get_fields вернул неверные данные" frm.login = "root" assert frm.login == "root", "дескриптор login вернул неверные данные" v = ValidateString(5, 10) assert v.validate("hello"), "метод validate вернул неверное значение" assert v.validate("hell") == False, "метод validate вернул неверное значение" assert ( v.validate("hello world!") == False ), "метод validate вернул неверное значение" class A: st = StringValue(validator=ValidateString(3, 10)) a = A() a.st = "hello" assert a.st == "hello", "дескриптор StringValue вернул неверное значение" a.st = "d" assert ( a.st == "hello" ), "дескриптор StringValue сохранил строку длиной меньше min_length" a.st = "dапарпаропропропропр" assert ( a.st == "hello" ), "дескриптор StringValue сохранил строку длиной больше max_length" a.st = "dапарпароп" assert ( a.st == "dапарпароп" ), "дескриптор StringValue сохранил строку длиной больше max_length" tests()