__getitem__ and arguments

K

KanZen

I'm trying to understand the difference between __setitem__ and an
ordinary method. For example:
def __getitem__(self, *args):
print len(args)
def normalMethod(self, *args):
print len(args)
a=A()
a.normalMethod(1, 2, 3) 3
a[1, 2, 3]
1

For __getitem__() the arguments become a tuple. I can't seem to find
this in the language spec. Can anybody explain this to me?

Thanks,
KanZen.
 
A

Andy Jewell

I'm trying to understand the difference between __setitem__ and an

ordinary method. For example:
def __getitem__(self, *args):
print len(args)
def normalMethod(self, *args):
print len(args)
a=A()
a.normalMethod(1, 2, 3)
3
a[1, 2, 3]

1

For __getitem__() the arguments become a tuple. I can't seem to find
this in the language spec. Can anybody explain this to me?

Thanks,
KanZen.


Maybe the following will help:

-------------8<---------- def __getitem__(self,*args):
print args
def test(self,*args):
print args

a=A()
a[1] (1,)
a[1:2] (slice(1, 2, None),)
a.__getitem__(1) (1,)
a.test(1)
(1,)
-------------8<----------

This tells us what we could already guess from the formal parameter list:
*args returns a tuple of the arguments.

Try:

-------------8<---------- def __getitem__(self,index):
print index
def test(self,index):
print index

a=A()
a[1] 1
a[1:2] slice(1, 2, None)
a.__getitem__(1) 1
a.test(1)
1
-------------8<----------

As you can see, both methods do the same. I think you're just seening the
effect of the variable arguments syntax.

I'm sure a Guru will correct me if I'm wrong, but I don't see evidence of a
'special case' here... ;-)

hth
-andyj
 
?

=?iso-8859-1?q?Fran=E7ois_Pinard?=

[KanZen]
def __getitem__(self, *args):
print len(args)

For __getitem__() the arguments become a tuple. I can't seem to find this
in the language spec. Can anybody explain this to me?

Hello, KanZen.

When you write an argument list as `*args', you _always_ get a tuple
of all arguments. Normally, one writes:

def __getitem__(self, argument):
...

as `__getitem__' only accepts one argument besides `self'. Of course,
you may well write:

def __getitem__(self, *arguments):
...

but then, `arguments' will always be a 1-tuple in practice, and
`arguments[0]' will contain the actual argument.

This being said, consider the call `a[1, 2, 3]' (it does not look like a
call, but we both know that under the scene, this is calling `__getitem__').
We may be tempted to think that it works a bit the same as an explicit
function call would work, like if it was written `a(1, 2, 3)', and the
confusion might come from there. Indeed, in `a(1, 2, 3)', there are three
arguments. `a[1, 2, 3]' is not the same, it calls the `__getattr__' of `a'
with a _single_ argument `1, 2, 3'. That single argument is really a tuple
itself.

Many Python users like to write tuples as `(1, 2, 3)', using superfluous
parentheses for strange reasons. :) They would likely write `a[(1, 2, 3)]'
as a way to over-stress that `a[]' accepts only one value within the
brackets. The writing `a[1, 2, 3]' is very legible because it is less
noisy, and you are right in preferring it. Yet you have to remember that
`1', `2' and `3' are not to become separate arguments for `__getitem__'.
The single argument will be what was within brackets, that is, a tuple.
 
B

Bengt Richter

On 20 Jul 2003 04:00:05 +0950 said:
Yes, because you've specified a key, which by definition is a single
argument.
But note that it can be more than a simple tuple (or less, if it's an int):
... def __getitem__(self, i): print i
...
>>> x=X()
>>> x[1] 1
>>> x[1:] slice(1, None, None)
>>> x[:1] slice(None, 1, None)
>>> x[:] slice(None, None, None)
>>> x[1, :, 1:, :1, 1:2, 1:2:3, (4,5), 6]
(1, slice(None, None, None), slice(1, None, None), slice(None, 1, None), slice(1, 2, None),
slice(1, 2, 3), (4, 5), 6)

Notice that (4,5) in there also as one of the indices.

Regards,
Bengt Richter
 
B

Ben Finney

I'm trying to understand the difference between __setitem__ and an
ordinary method. For example:

(presuming you mean __getitem__)
def __getitem__(self, *args):
print len(args)
def normalMethod(self, *args):
print len(args)
a=A()
a.normalMethod(1, 2, 3) 3
a[1, 2, 3]
1

The dictionary access syntax you used specifies a key, which forces
everything between [] to become a single argument. In this case, it's a
tuple, (1, 2, 3).

Thus, the args for A.__getitem__() is a tuple of length one, containing
the specified key: the tuple (1, 2, 3). That is, args is a tuple
containing a tuple.

No such coercion occurs for function syntax; the difference is that you
didn't invoke __getitem__ with function syntax.
.... def normal_method( self, *args ):
.... print len( args )
.... print type( args )
.... print args
.... def __getitem__( self, *args ):
.... print len( args )
.... print type( args )
.... print args
....
3
1

For __getitem__() the arguments become a tuple.

Yes, because you've specified a key, which by definition is a single
argument.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top