Question: I have a program with a function that takes a class initializer and list of objects. Each object consists of 3 variables id, value, and tag.

```
class Package():

    def __init__(self, id, value, name):
        if (value <= 0):
            raise ValueError("Amount must be greater than 0")
        self.id = id
        self.value = value
        self.tag = tag

 class Purchase():

    def submit(some_list):
        //Do stuff

def main():
    //Help here!
    parser = argparse.ArgumentParser()
    parser.add_argument("id", help="ID")
    parser.add_argument("value", help="Value")
    parser.add_argument("tag", help="Tag")
    args = parser.parse_args()
    some_list = [args.id, args.value, args.tag]
    submit(some_list)

```

I'm trying to implement argparse in main() so I can run the program by doing something like: `python foo.py "int0 [(int1, float1, int2), (int3, float2, int4) ....]"`. The number of objects in the list is variable and depends on the user input. 

```
initializer = num0

//First package object
package.id = num1
package.value = num2
package.tag = num3

//Second package object
package.id = num4
package.value = num5
package.tag = num6  

```

Answer: 
You can make a *custom [argument type](https://docs.python.org/2/library/argparse.html#type)* and use [`ast.literal_eval()`](https://docs.python.org/2/library/ast.html#ast.literal_eval) to parse the value.

Working sample:

```
import argparse
from ast import literal_eval

class Package():
    def __init__(self, id, value, tag):
        if (value <= 0):
            raise ValueError("Amount must be greater than 0")
        self.id = id
        self.value = value
        self.tag = tag

def packages(s):
    try:
        data = literal_eval(s)
    except:  # TODO: avoid bare except and handle more specific errors
        raise argparse.ArgumentTypeError("Invalid 'packages' format.")

    return [Package(*item) for item in data]

parser = argparse.ArgumentParser()
parser.add_argument('--packages', dest="packages", type=packages, nargs=1)
args = parser.parse_args()
print(args.packages)

```

Now if you would run the script, you would get a list of `Package` class instances printed:

```
$ python test.py --packages="[(1, 1.02, 3), (40, 2.32, 11)]"
[[<__main__.Package instance at 0x10a20d368>, <__main__.Package instance at 0x10a20d4d0>]]

```
I would prefer to be a bit more explicit and use a custom action:

```
import argparse

class PackageAction(argparse.Action):
    def __init__(self, *args, **kwargs):
        super(PackageAction, self).__init__(*args, **kwargs)
        self.nargs = 3

    def __call__(self, parser, namespace, values, option_string):
        lst = getattr(namespace, self.dest, []) or []
        a, b, c = values
        lst.append(Package(int(a), float(b), int(c)))
        setattr(namespace, self.dest, lst)

class Package(object):
    def __init__(self, foo, bar, baz):
        self.foo = foo
        self.bar = bar
        self.baz = baz

    def __repr__(self):
        return 'Package(%r, %r, %r)' % (self.foo, self.bar, self.baz)

parser = argparse.ArgumentParser()
parser.add_argument('--package', action=PackageAction)

print(parser.parse_args())

```

The usage here would look something like:

```
$ python packager.py --package 1 2 3 --package 4 5 6
Namespace(package=[Package(1, 2.0, 3), Package(4, 5.0, 6)])

```

One benefit is that you get slightly better default error handling ... e.g.:

```
$ python ~/sandbox/test.py --package 1 2 3 --package 4 5
usage: test.py [-h] [--package PACKAGE PACKAGE PACKAGE]
test.py: error: argument --package: expected 3 argument(s)

```

Of course, you can modify to suit your purposes -- specifically it would probably be good to provide a little extra [error handling](https://docs.python.org/3/library/argparse.html#exiting-methods) to `__call__`. e.g. you could do something like

```
parser.error('--package requires an int float and int')

```

if the user passed bad strings. You could also provide better variable names :-)