在寻找使用嵌套字典的方法时,我发现了nosklo发布的以下代码,我想解释一下。
class AutoVivification(dict):
"""Implementation of perl's autovivification feature."""
def __getitem__(self, item):
try:
return dict.__getitem__(self, item)
except KeyError:
value = self[item] = type(self)()
return value
测试:
a = AutoVivification()
a[1][2][3] = 4
a[1][3][3] = 5
a[1][2]['test'] = 6
print a
输出:
{1: {2: {'test': 6, 3: 4}, 3: {3: 5}}}
我是一个相当新手的程序员。我在业余时间学到了大部分我所知道的东西,我唯一的正式培训是在高中时的 Turbo Pascal。我理解并且能够以简单的方式使用类,例如使用__init__
、类方法,以及使用foo.man = 'choo'
.
我不知道方括号系列是如何通过类正确定向的(我认为它们是以__getitem__
某种方式调用的),并且不明白它们是如何被如此简洁地处理而不必单独调用该方法三次的。
我的印象是(dict)
类声明中的__init__
.
我以前用过try: except:
,不过,还是用非常简单的方式。在我看来try
,当它运行时,它正在调用一系列函数__getitem__
。我收集到,如果当前级别的字典存在,则尝试将通过并转到下一个字典。我认为except
,当有 a 时运行,KeyError
但我以前从未见过self
这样使用过。 Self
被当作字典对待,而我认为self
是class AutoVivification
……的一个实例,两者兼而有之吗?我从来没有像这样连续分配两次,foo = man = choo
但怀疑它value
指向self[item]
whileself[item]
指向的结果type(self)
。但type(self)
会返回如下内容:<class '__main__.AutoVivification'>
不会吗?我不知道末尾多余的圆括号是做什么用的。因为我不知道函数是如何被调用的,所以我不明白在哪里value
返回。
抱歉有这些问题!这里面有很多我不明白的地方,而且我不知道在哪里可以找到它,除非我花了几个小时阅读文档,而在这些文档中我保留的很少。这段代码看起来可以满足我的目的,但我想在使用它之前理解它。
如果您想知道我在使用嵌套字典的程序中要做什么:我正在尝试以天文比例保存地图数据。虽然我无法创建嵌套 4 次的 10^6 项的字典/列表(即 10^24 项!),但空间大部分是空的,因此我可以将空值完全排除在外,只有在有东西时才分配。困扰我的是处理字典的有效方法。