1

I want to be able to do something like the following

class C(object):
     # I store a series of values in some way
     # what do I need to implement to act like an array of arguments


c=C()
result=f(*c)

What does the *"operator" invoke on the instance in this usage?

Dave
  • 7,555
  • 8
  • 46
  • 88

3 Answers3

3

There are two ways to control the behavior of the * operator when it is used like that:

  1. Overload the __iter__ special method:

    >>> class C(object):
    ...     def __init__(self, lst):
    ...         self.lst = lst
    ...     def __iter__(self):
    ...         return iter(self.lst)
    ...
    >>> def f(a, b, c):
    ...     print "Arguments: ", a, b, c
    ...
    >>> c = C([1, 2, 3])
    >>> f(*c)
    Arguments:  1 2 3
    >>>
    
  2. Overload the __getitem__ special method:

    >>> class C(object):
    ...     def __init__(self, lst):
    ...         self.lst = lst
    ...     def __getitem__(self, key):
    ...         return self.lst[key]
    ...
    >>> def f(a, b, c):
    ...     print "Arguments: ", a, b, c
    ...
    >>> c = C([1, 2, 3])
    >>> f(*c)
    Arguments:  1 2 3
    >>>
    
1

People call this "positional expansion" or argument unpacking. Your instance should provide an __iter__ method, which is called when iterating over this object. However, I think the cleanest approach would be to subclass collections.Iterable, which is the abstract base class for all iterables in Python.

Note that this is the same question for keyword argument unpacking, requiring the object to be a mapping.

Edit: I am still trying to find the exact implementation in this case to see which C API call is used for unpacking. This would yield the precise answer to this question. Any pointers?

Community
  • 1
  • 1
Dr. Jan-Philip Gehrcke
  • 33,287
  • 14
  • 85
  • 130
1

One way you can do it is to subclass tuple or list.

kindall
  • 178,883
  • 35
  • 278
  • 309