Форум сайта python.su
0
Добрый день. Задача учебная. Есть класс, в нем словарь = значение. Заполняется так:
field[1, 'a'] = 25 field['a', 1] = 25 field['a', '1'] = 25 field['1', 'a'] = 25 field['1a'] = 25 field['a1'] = 25 field[1, 'A'] = 25 field['A', 1] = 25 field['A', '1'] = 25 field['1', 'A'] = 25 field['1A'] = 25 field['A1'] = 25.
class Field: def __init__(self): self.my_list = {} self.my_set_key = set() def to_my_list_tuple(self, str_val1, str_val2): pass # Обработка tuple def to_my_list_str(self, str_val1, str_val2=None): # Обработка str pass def my_new_key(self, key): #Любой получаемый ключ преобразую к виду 'a1', 'b555' pass def __getitem__(self, key): try: new_key = self.my_new_key(key) if new_key in self.my_list: return self.my_list[new_key] else: return None except: new_key = self.__getattr__(self, key) #работает, возможно и не самое лучшее решение # c __setitem не получилось использовать try: except def __setitem__(self, key, value): new_key = None new_key = self.my_new_key(key) if new_key is None: raise ValueError else: self.my_list[new_key] = value if new_key in self.my_set_key: pass else: self.my_set_key.add(new_key) def __iter__(self): self.froz_set = frozenset(self.my_set_key) for key in self.my_list: yield self.my_list[key] def __delitem__(self, key): new_key = self.my_new_key(key) del self.my_list[new_key] def __contains__(self, key): new_key = self.my_new_key(key) # print(new_key in self.my_list) return new_key in self.my_list def __getattr__(self, key): new_key = self.my_new_key(key) if new_key in self.my_list: return self.my_list[new_key] else: return None def __setattr__(self, key, value): pass
Отредактировано FishHook (Дек. 22, 2021 11:09:03)
Офлайн
568
class MyWeirdDict: def __getattr__(self, item): try: return super().__getattr__(item) except AttributeError as e: raise KeyError(item) from e def __getitem__(self, item): return getattr(self, item) def __setitem__(self, key, value): setattr(self, key, value) d = MyWeirdDict() d.key_1 = 34 d['key_2'] = 56 print(d.key_1) print(d.key_2) print(d['key_2']) class MyWeirdDict2: def __init__(self): self._dct = {} def __getattr__(self, item): return self._dct[item] def __getitem__(self, item): return self._dct[item] def __setitem__(self, key, value): self._dct[key] = value d = MyWeirdDict2() d.key_1 = 34 d['key_2'] = 56 print(d.key_1) print(d.key_2) print(d['key_2'])
Офлайн
0
FishHookВ данном решении получается, что значения не хранятся в одном объекте. key1 не попадет в словарь. В этом основная для меня проблема. И если ввести
field[1, 'a'] = 25 field.a1 = 555
Отредактировано Еленочка (Дек. 22, 2021 23:58:33)
Офлайн
857
ЕленочкаДа конечно, он не догнал, что нужно сделать. Что тут не так всё просто делается.
В данном решении получается, что значения не хранятся в одном объекте.
И если ввестиТо значение не перезапишется.field[1, 'a'] = 25 field.a1 = 555
Офлайн
568
py.user.nextну теперь то всё понятно! Декомпозировал в структурной парадигме как боженька
Нужно написать одну функцию, которая берёт любую хрень эту и отображает её в одну точную хрень
Офлайн
857
FishHookДа я вот набросал без оптимизаций
ну теперь то всё понятно! Декомпозировал
>>> def f(key): ... if type(key) is str: ... a, b = key[:len(key) // 2], key[len(key) // 2:] ... elif type(key) is tuple: ... a, b = tuple(map(str, key)) ... out = None ... if a[0].isalpha() and b[0].isdigit(): ... out = a.lower() + b ... elif a[0].isdigit() and b[0].isalpha(): ... out = b.lower() + a ... else: ... raise ValueError ... return out ... >>> lst = ['1a', ... 'a1', ... '1A', ... 'A1', ... (1, 'a'), ... (1, 'A'), ... ('a', 1), ... ('A', 1), ... ('a', '1'), ... ('A', '1'), ... ('1', 'a'), ... ('1', 'A')] >>> >>> for i in lst: ... print(repr(i), '->', repr(f(i))) ... '1a' -> 'a1' 'a1' -> 'a1' '1A' -> 'a1' 'A1' -> 'a1' (1, 'a') -> 'a1' (1, 'A') -> 'a1' ('a', 1) -> 'a1' ('A', 1) -> 'a1' ('a', '1') -> 'a1' ('A', '1') -> 'a1' ('1', 'a') -> 'a1' ('1', 'A') -> 'a1' >>> >>> lst = ['123abc', ... 'abc123', ... '123ABC', ... 'ABC123', ... (123, 'abc'), ... (123, 'ABC'), ... ('abc', 123), ... ('ABC', 123), ... ('abc', '123'), ... ('ABC', '123'), ... ('123', 'abc'), ... ('123', 'ABC')] >>> >>> for i in lst: ... print(repr(i), '->', repr(f(i))) ... '123abc' -> 'abc123' 'abc123' -> 'abc123' '123ABC' -> 'abc123' 'ABC123' -> 'abc123' (123, 'abc') -> 'abc123' (123, 'ABC') -> 'abc123' ('abc', 123) -> 'abc123' ('ABC', 123) -> 'abc123' ('abc', '123') -> 'abc123' ('ABC', '123') -> 'abc123' ('123', 'abc') -> 'abc123' ('123', 'ABC') -> 'abc123' >>>
Отредактировано py.user.next (Дек. 23, 2021 11:30:49)
Офлайн
568
Теперь мне нужно дополнить ключами вида field.a1 = 25задача была по крайней мере сформулирована следующим образом
__setitem__ и __setattr__ в одном классе
И вот тут не нашла еще способ как совместить __setattr__ + setitem, и не потерять функционал старых методов.
Отредактировано FishHook (Дек. 23, 2021 11:54:09)
Офлайн
0
import re class Field: def __init__(self): self.my_list = {} self.my_set_key = set() def to_my_list_tuple(self, str_val1, str_val2): key_str = None key_int = None if isinstance(str_val1, int): if str_val1 > 0: if isinstance(str_val2, str): if len(str_val2) == 1 and str_val2.isalpha(): key_str = str_val2.lower() key_int = str_val1 return key_str, key_int else: raise ValueError # return key_str, key_int else: raise ValueError # return key_str, key_int else: raise ValueError # return key_str, key_int elif isinstance(str_val2, int): if str_val2 > 0: if isinstance(str_val1, str): if len(str_val1) == 1 and str_val1.isalpha(): key_str = str_val1.lower() key_int = str_val2 return key_str, key_int else: raise ValueError # return key_str, key_int else: raise ValueError # return key_str, key_int else: raise ValueError # return key_str, key_int elif isinstance(str_val1, str) and isinstance(str_val2, str): if ('.' in str_val1) or ('.' in str_val2) or ('-' in str_val1) or ('-' in str_val2): raise ValueError # return key_str, key_int else: if (str_val1.isdigit()) and (int(str_val1) > 0): if str_val2.isalpha() and len(str_val2) == 1: key_str = str_val2.lower() key_int = str_val1 return key_str, key_int else: raise ValueError # return key_str, key_int elif str_val1.isalpha() and len(str_val1) == 1: if (str_val2.isdigit()) and (int(str_val2) > 0): key_str = str_val1.lower() key_int = int(str_val2) return key_str, key_int else: raise ValueError # return key_str, key_int else: raise ValueError # return key_str, key_int def to_my_list_str(self, str_val1, str_val2=None): key_str = None key_int = None if isinstance(str_val1, str) and (str_val2 is None): if ('.' in str_val1) or ('-' in str_val1): raise ValueError # return key_str, key_int elif len(str_val1) == 1: raise ValueError # return key_str, key_int else: num_value = re.findall(r'\d+', str_val1) match_value = re.findall(r'(?i)[a-z,A-Z]+', str_val1) match_value = ''.join(match_value) if len(match_value) == 1: key_str = match_value.lower() key_int = int("".join(list(map(str, num_value)))) return key_str, key_int else: raise ValueError # return key_str, key_int else: raise ValueError # return key_str, key_int def str_my_list(self, key_str, key_int): if key_str is None and key_int is None: new_key = None else: new_key = str(key_str) + str(key_int) return new_key def my_new_key(self, key): if isinstance(key, tuple) or isinstance(key, str): if isinstance(key, tuple): key_str, key_int = self.to_my_list_tuple(str_val1=key[0], str_val2=key[1]) new_key = self.str_my_list(key_str=key_str, key_int=key_int) return new_key elif isinstance(key, str): key_str, key_int = self.to_my_list_str(str_val1=key, str_val2=None) new_key = self.str_my_list(key_str=key_str, key_int=key_int) return new_key else: raise TypeError def __setitem__(self, key, value): new_key = None new_key = self.my_new_key(key) if new_key is None: raise ValueError else: self.my_list[new_key] = value if new_key in self.my_set_key: pass else: self.my_set_key.add(new_key) def __getitem__(self, key): new_key = self.my_new_key(key) if new_key in self.my_list: return self.my_list[new_key] else: return None def __iter__(self): self.froz_set = frozenset(self.my_set_key) for key in self.my_list: yield key def __delitem__(self, key): new_key = self.my_new_key(key) # del self.my_set_key[new_key] del self.my_list[new_key] def __contains__(self, key): new_key = self.my_new_key(key) # print(new_key in self.my_list) return new_key in self.my_list
def __getitem__(self, key): try: new_key = self.my_new_key(key) if new_key in self.my_list: return self.my_list[new_key] else: return None except: new_key = self.__getattr__(self, key)
Офлайн
857
FishHookА если бы она спросила “как правильно спрыгнуть с девятого этажа?”, ты бы тоже стал ей советовать белые тапочки надеть?
задача была по крайней мере сформулирована следующим образомЕленочка
__setitem__ и __setattr__ в одном классе
Нахуа?ЕленочкаЭто ещё что такое? Может, подучить что-нибудь сначала, почитать там? Если ты берёшь и маленькие, и большие буквы, то зачем там флажок игнорирования регистра? А запятая вот эта умиляет просто. Да… надо учиться, а то так и будешь херню смешную писать.match_value = re.findall(r'(?i)[a-z,A-Z]+', str_val1)
ЕленочкаХм, интересно, для чего здесь list используется? Для того, чтобы сказать, что масло оно масляное?key_int = int("".join(list(map(str, num_value))))
>>> ''.join(map(str, range(5))) '01234' >>>
ЕленочкаО, ещё куча операций.if isinstance(key, tuple) or isinstance(key, str):
>>> isinstance('a', (tuple, str)) True >>> isinstance((1, 2), (tuple, str)) True >>> isinstance(1, (tuple, str)) False >>>
Отредактировано py.user.next (Дек. 23, 2021 15:53:40)
Офлайн
124
ЕленочкаУ вас эти задачи без теории?Имеется ввиду к ним прилагается теоретическая часть или какие-нибудь теги для поиска
Добрый день. Задача учебная.
Офлайн