Below is the source code of the collections
module in Python 2.7. I feel confused by the way the OrderedDict
initializes its __root
variable. Why does it use try
and except
, is it necessary? Why can't it just use
self.__root = root = [] # sentinel node
root[:] = [root, root, None]
self.__map = {}
self.__update(*args, **kwds)
to initialize self.__root
?
thanks a lot ...
class OrderedDict(dict):
'Dictionary that remembers insertion order'
# An inherited dict maps keys to values.
# The inherited dict provides __getitem__, __len__, __contains__, and get.
# The remaining methods are order-aware.
# Big-O running times for all methods are the same as regular dictionaries.
# The internal self.__map dict maps keys to links in a doubly linked list.
# The circular doubly linked list starts and ends with a sentinel element.
# The sentinel element never gets deleted (this simplifies the algorithm).
# Each link is stored as a list of length three: [PREV, NEXT, KEY].
def __init__(self, *args, **kwds):
'''Initialize an ordered dictionary. The signature is the same as
regular dictionaries, but keyword arguments are not recommended because
their insertion order is arbitrary.
'''
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
try:
self.__root
except AttributeError:
self.__root = root = [] # sentinel node
root[:] = [root, root, None]
self.__map = {}
self.__update(*args, **kwds)
I found a discussion here (worth noting that Raymond Hettinger is a python core developer).
Essentially it seems to be a precaution for cases where users call
__init__
a second time (instead ofupdate
) like this:While very uncommon this is mainly important for consistency with
dict.__init__
which can also be called a second time instead ofdict.update
: