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__
method of
Foo but with no success. Below is the example 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[...]
is not equivalent to foo.__getitem__(...)
, something
behind the scene is done for the former. My question is what exactly and how
can I make foo[2, a=10]
to work, if at all.
Python allows implicit tuple creation (without 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)
is not a valid tuple literal:
In [6]: (2, a=10)
File "<ipython-input-1-7dc03602f595>", line 1
(2, a=10)
^
SyntaxError: invalid syntax
Simply put, you can't make foo[2, a=10]
to work, because it's a syntax error no matter how you tweak your __getitem__
implementation.
I'd probably define an ordinary method e.g. get
and use it like Foo.get(2, a=10)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With