__getitem__ and arguments

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • KanZen

    __getitem__ and arguments

    I'm trying to understand the difference between __setitem__ and an
    ordinary method. For example:
    [color=blue][color=green][color=darkred]
    >>> class A(object):[/color][/color][/color]
    def __getitem__(sel f, *args):
    print len(args)
    def normalMethod(se lf, *args):
    print len(args)
    [color=blue][color=green][color=darkred]
    >>> a=A()
    >>> a.normalMethod( 1, 2, 3)[/color][/color][/color]
    3[color=blue][color=green][color=darkred]
    >>> a[1, 2, 3][/color][/color][/color]
    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.
  • Ben Finney

    #2
    Re: __getitem__ and arguments

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

    (presuming you mean __getitem__)
    [color=blue][color=green][color=darkred]
    >>>> class A(object):[/color][/color]
    > def __getitem__(sel f, *args):
    > print len(args)
    > def normalMethod(se lf, *args):
    > print len(args)
    >[color=green][color=darkred]
    >>>> a=A()
    >>>> a.normalMethod( 1, 2, 3)[/color][/color]
    > 3[color=green][color=darkred]
    >>>> a[1, 2, 3][/color][/color]
    > 1[/color]

    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.
    [color=blue][color=green][color=darkred]
    >>> class A:[/color][/color][/color]
    .... 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
    ....[color=blue][color=green][color=darkred]
    >>> a = A()
    >>> a.normal_method ( 1, 2, 3 )[/color][/color][/color]
    3
    <type 'tuple'>
    (1, 2, 3)[color=blue][color=green][color=darkred]
    >>> a[ 1, 2, 3 ][/color][/color][/color]
    1
    <type 'tuple'>
    ((1, 2, 3),)[color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]
    [color=blue]
    > For __getitem__() the arguments become a tuple.[/color]

    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

    Comment

    • François Pinard

      #3
      Re: __getitem__ and arguments

      [KanZen]
      [color=blue][color=green][color=darkred]
      > >>> class A(object):[/color][/color]
      > def __getitem__(sel f, *args):
      > print len(args)[/color]
      [color=blue][color=green][color=darkred]
      > >>> a=A()
      > >>> a[1, 2, 3][/color][/color]
      > 1[/color]
      [color=blue]
      > For __getitem__() the arguments become a tuple. I can't seem to find this
      > in the language spec. Can anybody explain this to me?[/color]

      Hello, KanZen.

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

      def __getitem__(sel f, argument):
      ...

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

      def __getitem__(sel f, *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

      Comment

      • Andy Jewell

        #4
        Re: __getitem__ and arguments

        On Saturday 19 Jul 2003 10:10 am, KanZen wrote:[color=blue]
        > I'm trying to understand the difference between __setitem__ and an
        >
        > ordinary method. For example:[color=green][color=darkred]
        > >>> class A(object):[/color][/color]
        >
        > def __getitem__(sel f, *args):
        > print len(args)
        > def normalMethod(se lf, *args):
        > print len(args)
        >[color=green][color=darkred]
        > >>> a=A()
        > >>> a.normalMethod( 1, 2, 3)[/color][/color]
        >
        > 3
        >[color=green][color=darkred]
        > >>> a[1, 2, 3][/color][/color]
        >
        > 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.[/color]


        Maybe the following will help:

        -------------8<----------[color=blue][color=green][color=darkred]
        >>> class A(object):[/color][/color][/color]
        def __getitem__(sel f,*args):
        print args
        def test(self,*args ):
        print args

        [color=blue][color=green][color=darkred]
        >>> a=A()
        >>> a[1][/color][/color][/color]
        (1,)[color=blue][color=green][color=darkred]
        >>> a[1:2][/color][/color][/color]
        (slice(1, 2, None),)[color=blue][color=green][color=darkred]
        >>> a.__getitem__(1 )[/color][/color][/color]
        (1,)[color=blue][color=green][color=darkred]
        >>> a.test(1)[/color][/color][/color]
        (1,)
        -------------8<----------

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

        Try:

        -------------8<----------[color=blue][color=green][color=darkred]
        >>> class A(object):[/color][/color][/color]
        def __getitem__(sel f,index):
        print index
        def test(self,index ):
        print index

        [color=blue][color=green][color=darkred]
        >>> a=A()
        >>> a[1][/color][/color][/color]
        1[color=blue][color=green][color=darkred]
        >>> a[1:2][/color][/color][/color]
        slice(1, 2, None)[color=blue][color=green][color=darkred]
        >>> a.__getitem__(1 )[/color][/color][/color]
        1[color=blue][color=green][color=darkred]
        >>> a.test(1)[/color][/color][/color]
        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 ofa
        'special case' here... ;-)

        hth
        -andyj

        Comment

        • Bengt Richter

          #5
          Re: __getitem__ and arguments

          On 20 Jul 2003 04:00:05 +0950, Ben Finney <[email protected]> wrote:
          [...][color=blue]
          >[color=green]
          >> For __getitem__() the arguments become a tuple.[/color]
          >
          >Yes, because you've specified a key, which by definition is a single
          >argument.
          >[/color]
          But note that it can be more than a simple tuple (or less, if it's an int):
          [color=blue][color=green][color=darkred]
          >>> class X(object):[/color][/color][/color]
          ... def __getitem__(sel f, i): print i
          ...[color=blue][color=green][color=darkred]
          >>> x=X()
          >>> x[1][/color][/color][/color]
          1[color=blue][color=green][color=darkred]
          >>> x[1:][/color][/color][/color]
          slice(1, None, None)[color=blue][color=green][color=darkred]
          >>> x[:1][/color][/color][/color]
          slice(None, 1, None)[color=blue][color=green][color=darkred]
          >>> x[:][/color][/color][/color]
          slice(None, None, None)[color=blue][color=green][color=darkred]
          >>> x[1, :, 1:, :1, 1:2, 1:2:3, (4,5), 6][/color][/color][/color]
          (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

          Comment

          Working...