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是在'库'中,所以编译器可以假设更少?还是其他一些原因?
操作:
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 dict
S ^ __getitem__
只为关键返回值或抛出,如果它不存在.
但是子类也可以实现该__missing__
方法 - 如果他们想要自定义行为,如果密钥不存在于dict中(在查找期间).