我创建了一个扩展dict
和set
的类(更确切地说,我扩展了collections.abc.MutableMapping
和MutableSet
)。现在我想正确覆盖方法keys()
。
此类表示一组名为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
在哪里?答案 0 :(得分:0)
我还没有找到任何方法将某些内容转换为dict_keys
类型,但在阅读了介绍访问键和值(PEP 3106)的新方法的PEP之后,看起来dict_keys
被引入了
返回一个类似于集合或无序的容器对象,其内容是从基础字典派生的,而不是作为密钥副本的列表等。
考虑到这一点,看起来您可以使用keys()
方法而不是列表返回生成器对象。
以下是PEP的伪代码:
class dict:
# Omitting all other dict methods for brevity.
def keys(self):
return d_keys(self)
class d_keys:
def __init__(self, d):
self.__d = d
def __len__(self):
return len(self.__d)
def __contains__(self, key):
return key in self.__d
def __iter__(self):
for key in self.__d:
yield key
答案 1 :(得分:0)
Python3文档说dict.keys()
返回值类型(即视图)是"类似于",所以你的返回值应该是" set-like"同样。
dict.keys(),dict.values()和dict.items()返回的对象 是视图对象。它们提供了字典的动态视图 条目,表示当字典更改时,视图 反映了这些变化。
可以迭代字典视图以产生它们 各自的数据和支持会员资格测试:
...
键视图设置类似,因为它们的条目是唯一且可清除的。 如果所有值都是可清除的,那么(键,值)对是唯一的 hashable,那么items视图也是类似的。 (值视图不是 由于条目通常不是唯一的,因此被视为类似集合。)对于 类似于集合的视图,为抽象基础定义的所有操作 class collections.abc.Set可用(例如,==,<,或^)。
全文: https://docs.python.org/3/library/stdtypes.html#dict-views
答案 2 :(得分:0)
这已经为您处理了! collections.abc.MutableMapping
包含keys
的合理默认实施,提供与dict.keys
相同的界面。
只需删除您的keys
方法,即可使用继承的实现。