__getitem__ and arguments

Discussion in 'Python' started by KanZen, Jul 19, 2003.

  1. KanZen

    KanZen Guest

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

    >>> class A(object):

    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.
    KanZen, Jul 19, 2003
    #1
    1. Advertising

  2. KanZen

    Andy Jewell Guest

    On Saturday 19 Jul 2003 10:10 am, KanZen wrote:
    > I'm trying to understand the difference between __setitem__ and an
    >
    > ordinary method. For example:
    > >>> class A(object):

    >
    > 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<----------
    >>> class A(object):

    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<----------
    >>> class A(object):

    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
    Andy Jewell, Jul 19, 2003
    #2
    1. Advertising

  3. [KanZen]

    > >>> class A(object):

    > def __getitem__(self, *args):
    > print len(args)


    > >>> a=A()
    > >>> 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?


    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.

    --
    Fran├žois Pinard http://www.iro.umontreal.ca/~pinard
    =?iso-8859-1?q?Fran=E7ois_Pinard?=, Jul 19, 2003
    #3
  4. On 20 Jul 2003 04:00:05 +0950, Ben Finney <> wrote:
    [...]
    >
    >> For __getitem__() the arguments become a tuple.

    >
    >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):

    >>> class X(object):

    ... 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
    Bengt Richter, Jul 19, 2003
    #4
  5. KanZen

    Ben Finney Guest

    On 19 Jul 2003 02:10:25 -0700, KanZen wrote:
    > I'm trying to understand the difference between __setitem__ and an
    > ordinary method. For example:


    (presuming you mean __getitem__)

    >>>> class A(object):

    > 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.

    >>> class A:

    .... 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
    ....
    >>> a = A()
    >>> a.normal_method( 1, 2, 3 )

    3
    <type 'tuple'>
    (1, 2, 3)
    >>> a[ 1, 2, 3 ]

    1
    <type 'tuple'>
    ((1, 2, 3),)
    >>>


    > For __getitem__() the arguments become a tuple.


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

    --
    \ "He may look like an idiot and talk like an idiot but don't let |
    `\ that fool you. He really is an idiot." -- Groucho Marx |
    _o__) |
    http://bignose.squidly.org/ 9CFE12B0 791A4267 887F520C B7AC2E51 BD41714B
    Ben Finney, Jul 19, 2003
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andrew Bennetts

    Re: __getitem__ and classmethod/staticmethod

    Andrew Bennetts, Jun 25, 2004, in forum: Python
    Replies:
    0
    Views:
    480
    Andrew Bennetts
    Jun 25, 2004
  2. Karl Chen
    Replies:
    0
    Views:
    334
    Karl Chen
    Jun 25, 2004
  3. Steven Bethard

    unittest.TestCase, lambda and __getitem__

    Steven Bethard, Sep 13, 2004, in forum: Python
    Replies:
    7
    Views:
    448
    Alex Martelli
    Sep 14, 2004
  4. It's me
    Replies:
    0
    Views:
    276
    It's me
    Feb 22, 2005
  5. timh
    Replies:
    6
    Views:
    291
    Dave Angel
    May 18, 2009
Loading...

Share This Page