EDIT: я добавил класс и некоторую информацию, увидев новое сообщение.
Я создал класс, который расширяет dict
и set
(точнее, я протянул collections.abc.MutableMapping
и MutableSet
). Теперь я хочу правильно переопределить метод keys()
.Как правильно переопределить ключи методов() при расширении dict (в python3)
Этот класс представляет собой набор других объектов, называемый Measurand
:
class Measurands(MutableSet, MutableMapping):
@property
def measurands(self):
return self._measurands
@measurands.setter
def measurands(self, val):
self._measurands = []
for el in val:
self.add(el)
def __init__(self, arg=None):
if arg is None:
self.measurands = []
else:
try:
measurands = arg.measurands
except AttributeError:
if isinstance(arg, Iterable):
measurands = list(arg)
else:
measurands = [arg]
self.measurands = measurands
def __iter__(self):
return iter(self.measurands)
def __getitem__(self, key):
for m in self:
if m.id == key:
return m
raise KeyError(key)
def __contains__(self, el_x):
is_in = False
for el in self:
if el_x.id == el.id:
is_in = True
break
return is_in
def add(self, el):
try:
self[el.id].session_ids |= el.session_ids
except KeyError:
self[el.id] = Measurand(el)
def _discard(self, key):
res = False
for i, m in enumerate(self):
if m.id == key:
del self.measurands[i]
res = True
break
return res
def __delitem__(self, key):
res = self._discard(self, key)
if not res:
raise KeyError(key)
def discard(self, key):
self._discard(self, key)
def remove(self, key):
self.__delitem__(self, key)
def __len__(self):
return len(self.measurands)
def __setitem__(self, key, value):
res = False
value_true = Measurand(value)
for i, m in enumerate(self):
if m.id == key:
res = True
if value.id == key:
self.measurands[i] = value_true
else:
raise KeyError(key)
break
if not res:
self.measurands.append(value_true)
def __str__(self):
string = "Measurands({"
for m in self:
string += str(m)
string += ", "
if string:
string = string[:-2]
string += "})"
return string
Проблема является метод по умолчанию keys
возвращает «список» Measurand
объектов. Это не то, что я хочу. Ключами должны быть имущество id
объектов Measurand
.
На данный момент я возвращаю простой list
, но я бы вернул dict_keys
или объект collection.abc.KeysView
. К несчастью, dict_keys
не является глобальным именем.
- Где
dict_keys
? - Это правильный/питонический способ сделать это?
* «Я хочу правильно переопределить метод' dict() '" * - что? 'dict' - не метод. Вы хотите иметь возможность делать 'dict (instance_of_your_thing)'? Не могли бы вы дать [mcve] вашей реализации и объяснить проблему на примере? – jonrsharpe
Судя по названию, я думаю, он имел в виду, что хочет правильно переопределить 'keys()' и сделал опечатку в актуальном вопросе – wpercy
@wilbur ах! Это имеет смысл. OP? – jonrsharpe