Domanda

The Dictionary __getitem__ method does not seem to work the same way as it does for List, and it is causing me headaches. Here is what I mean:

If I subclass list, I can overload __getitem__ as:

class myList(list):
    def __getitem__(self,index):
        if isinstance(index,int):
            #do one thing
        if isinstance(index,slice):
            #do another thing

If I subclass dict, however, the __getitem__ does not expose index, but key instead as in:

class myDict(dict):
    def __getitem__(self,key):
        #Here I want to inspect the INDEX, but only have access to key!

So, my question is how can I intercept the index of a dict, instead of just the key?

Example use case:

a = myDict()
a['scalar'] = 1  # Create dictionary entry called 'scalar', and assign 1
a['vector_1'] = [1,2,3,4,5]  # I want all subsequent vectors to be 5 long
a['vector_2'][[0,1,2]] = [1,2,3]  # I want to intercept this and force vector_2 to be 5 long
print(a['vector_2'])
[1,2,3,0,0]
a['test']  # This should throw a KeyError
a['test'][[0,2,3]]  # So should this
È stato utile?

Soluzione

Dictionaries have no order; there is no index to pass in; this is why Python can use the same syntax ([..]) and the same magic method (__getitem__) for both lists and dictionaries.

When you index a dictionary on an integer like 0, the dictionary treats that like any other key:

>>> d = {'foo': 'bar', 0: 42}
>>> d.keys()
[0, 'foo']
>>> d[0]
42
>>> d['foo']
'bar'

Chained indexing applies to return values; the expression:

a['vector_2'][0, 1, 2]

is executed as:

_result = a['vector_2']  # via a.__getitem__('vector_2')
_result[0, 1, 2]         # via _result.__getitem__((0, 1, 2))

so if you want values in your dictionary to behave in a certain way, you must return objects that support those operations.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top