如果某个键不在some_dict中,为什么some_dict ['key'] = somevalue会起作用?

bar*_*oli 3 python dictionary operators

我知道我可以通过这样做在python dict中添加一个新的键/值

some_dict['absent_key'] = somevalue
Run Code Online (Sandbox Code Playgroud)

但我真的不了解内部工作.

我曾经认为字典表现得像C++地图.如果[]操作符不存在,则为给定键创建元素,然后返回对它的引用,以便可以在运算符的同一行中为其赋值=.

但是,C++中的这种行为的结果是,如果我们从映射中查询不存在的键的值,则会为该键创建该元素,并返回值类型的默认值而不是错误.在python中,这会抛出一个KeyError.

所以我不明白的是:如何,因为[]运算符必须=在python 之前进行评估(我认为?),它的行为会有所不同,这取决于结果是读取还是分配了一个值(它不应该在那里知道)表达式评价的要点)?

python评估表达式的顺序有区别吗?或者解释器只是更聪明,因为字典是一个硬编码类型,所以它更准确地知道它的行为,而std :: map是在'库'中,所以编译器可以假设更少?还是其他一些原因?

MSe*_*ert 5

操作:

some_dict[key]
Run Code Online (Sandbox Code Playgroud)

some_dict[key] = value
Run Code Online (Sandbox Code Playgroud)

del some_dict[key]
Run Code Online (Sandbox Code Playgroud)

使用对象的不同的特殊方法:__getitem__,__setitem____delitem__.因此,不只是一个operator([])实现了它们.

也许一个例子可以说明:

class Something(dict):  # subclassing dict
    def __getitem__(self, key):
        print('trying to get', key)
        return super().__getitem__(key)
    def __setitem__(self, key, value):
        print('trying to set', key, 'to', value)
        return super().__setitem__(key, value)
    def __delitem__(self, key):
        print('trying to delete', key)
        return super().__delitem__(key)
Run Code Online (Sandbox Code Playgroud)

测试:

>>> s = Something({'a': 1, 'b': 2})
>>> s['a']
trying to get a
1

>>> s['c'] = 10
trying to set c to 10

>>> del s['b']
trying to delete b
Run Code Online (Sandbox Code Playgroud)

所以这取决于它们的实施方式.在普通的Python dictS ^ __getitem__只为关键返回值或抛出,如果它不存在.

但是子类也可以实现该__missing__方法 - 如果他们想要自定义行为,如果密钥不存在于dict中(在查找期间).