Using keyword arguments in __getitem__ method in Python
I want to define a class Foo whose objects can be used like foo[1, a=2]
      
        
        
        
      
    .
I tried to achieve this by decorating the __getitem__
      
        
        
        
      
    
Foo method , but with no success. Below is a sample code.
def decorator(func):
    def func_(*args, **kewargs):
        if 'a' in kewargs:
            args = list(args) + [kewargs['a']]
            return func(*args)
        else:
            return func(*args)
    return func_
class Foo(object):
    @decorator
    def __getitem__(self, *items):
        return items
foo = Foo()
>>> foo.__getitem__(2, a=10)
(2, 10)
>>> foo[2, a=10]
SyntaxError: invalid syntax
      
        
        
        
      
    So, foo[...]
      
        
        
        
      
    not equivalent foo.__getitem__(...)
      
        
        
        
      
    , something behind the scenes is done for the former. My question is what exactly and how can I get it foo[2, a=10]
      
        
        
        
      
    to work, if at all.
Python allows you to create implicit tuples (no parentheses):
In [2]: tup = 1, 2, 3
In [3]: tup
Out[3]: (1, 2, 3)
      
        
        
        
      
    And it works the same inside square brackets:
In [4]: d = {(1, 2, 3): 4}
In [5]: d[1, 2, 3]
Out[5]: 4
      
        
        
        
      
    But (2, a=10)
      
        
        
        
      
    it is not a valid literal:
In [6]: (2, a=10)
  File "<ipython-input-1-7dc03602f595>", line 1
    (2, a=10)
         ^
SyntaxError: invalid syntax
      
        
        
        
      
    Simply put, you can't get it foo[2, a=10]
      
        
        
        
      
    to work because it's a syntax error no matter how you set up the implementation __getitem__
      
        
        
        
      
    .
I would probably define a normal method like. get
      
        
        
        
      
    and use it like Foo.get(2, a=10)
      
        
        
        
      
    .
This is suggested for python 3.6
It is currently a syntax error to use keyword arguments for indexing.
However, PEP472 ( https://www.python.org/dev/peps/pep-0472/ ) offers this addition to the python syntax.
Workarounds
The PEP also shows workarounds that are currently valid:
 foo[2, "a":10]
      
        
        
        
      
     or foo[2, {"a":10}]