免责声明:这个答案主要是为了说明 Python 允许您做的一件(众多)事情。此外,您可能应该不想以这种方式做事(您可以做事并不意味着您应该)
这就是说,getitem(self, key) 的文档指出:
对于序列类型,接受的键应该是整数和切片
对象。
这意味着任何想要模仿 sequence type 行为的类(例如列表)都必须准备好实现__getitem__,其中键可以是slice 类型.这(某种)解释了(或至少在某种程度上与)为什么在你的字典中当你尝试做b[slice(st,en)] = 'bla ' 时你得到一个TypeError: unhashable type:这是因为它试图使用slice(st, en) 实例作为字典键。 slice 对象不可散列,因此不能用作 dict 键。 dict 类型不是序列类型,因此尝试对字典进行切片没有任何意义。
假设你有:
{
...“富”:1,
...“酒吧”:2,
...“巴兹”:3,
... }
从'foo' 到'bar' 的slice 是什么意思?你会按照你输入的顺序返回这组键吗? ('foo','bar','baz')? Python 不知道这一点。会是他们的__hash__吗?这是内部的,在切片时毫无意义。
说了这么多,这是一件非常非常糟糕的事情……但这“有效”:
import datetime
class DatetimeDict(dict):
def __getitem__(self, key):
if isinstance(key, slice):
sliced = {}
start_dt = key.start
stop_dt = key.stop
step = key.step or 1
internal_keys = sorted(self.keys())
if start_dt is None:
start_index = 0
else:
start_index = internal_keys.index(start_dt)
end_index = internal_keys.index(stop_dt)
for i in range(start_index, end_index, step):
sliced.update({internal_keys[i]: self[internal_keys[i]]})
return sliced
else:
return super(DatetimeDict, self).__getitem__(key)
def __setitem__(self, key, val):
return super(DatetimeDict, self).__setitem__(key, val)
a = DatetimeDict()
a[datetime.datetime.strptime('2014/01/01', '%Y/%m/%d')] = 'foo',
a[datetime.datetime.strptime('2014/01/02', '%Y/%m/%d')] = 'bar',
a[datetime.datetime.strptime('2014/01/03', '%Y/%m/%d')] = 'baz',
a[datetime.datetime.strptime('2014/01/04', '%Y/%m/%d')] = 'bla',
from_dt = datetime.datetime.strptime('2014/01/02', '%Y/%m/%d')
to_dt = datetime.datetime.strptime('2014/01/04', '%Y/%m/%d')
print a[from_dt:to_dt]
这个输出:
{
datetime.datetime(2014, 1, 2, 0, 0): ('bar',),
datetime.datetime(2014, 1, 3, 0, 0): ('baz',)
}
但是很糟糕,很糟糕......DatetimeDict 变成了一个 奇怪 结构,它是一个字典,但同时表现得有点像序列类型...... 糟糕。
编辑(重新阅读后,我很确定我误解了这个问题)
你实际上并没有试图分割dict,你在哪里?当我学会阅读的那一天,我将征服世界...... :-D
如果您想要使用一系列日期时间作为dict 键,我建议您只需将start 和end 放在tuple 中:
>>> import datetime
>>> st = datetime.datetime.strptime('2014/01/01', '%Y/%m/%d')
>>> en = datetime.datetime.strptime('2014/01/02', '%Y/%m/%d')
>>> key = (st, en)
>>> a = {}
>>> a[key] = 'foo'
>>> print a
{(datetime.datetime(2014, 1, 1, 0, 0), datetime.datetime(2014, 1, 2, 0, 0)): 'foo'}
Weeeelllll...至少我学会了切片之类的东西...大声笑...