This question already had many highly upvoted answers and an accepted answer, but all of them so far were distracted by various ways to express the boolean problem and missed a crucial point:
I have a python script that can receive either zero or three command
line arguments. (Either it runs on default behavior or needs all three
values specified)
This logic should not be the responsibility of library code in the first place, rather it should be handled by the command-line parsing (usually argparse
module in Python). Don't bother writing a complex if statement, instead prefer to setup your argument parser something like this:
#!/usr/bin/env python
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', nargs=3, default=['x', 'y', 'z'])
args = parser.parse_args()
print(args.foo)
And yes, it should be an option not a positional argument, because it is after all optional.
edited: To address the concern of LarsH in the comments, below is an example of how you could write it if you were certain you wanted the interface with either 3 or 0 positional args. I am of the opinion that the previous interface is better style (because optional arguments should be options), but here's an alternative approach for the sake of completeness. Note we're overriding kwarg usage
when creating your parser, because argparse
will auto-generate a misleading usage message otherwise!
#!/usr/bin/env python
import argparse
parser = argparse.ArgumentParser(usage='%(prog)s [-h] [a b c]\n')
parser.add_argument('abc', nargs='*', help='specify 3 or 0 items', default=['x', 'y', 'z'])
args = parser.parse_args()
if len(args.abc) != 3:
parser.error('expected 3 arguments')
print(args.abc)
Here are some usage examples:
# default case
$ ./three_or_none.py
['x', 'y', 'z']
# explicit case
$ ./three_or_none.py 1 2 3
['1', '2', '3']
# example failure mode
$ ./three_or_none.py 1 2
usage: three_or_none.py [-h] [a b c]
three_or_none.py: error: expected 3 arguments