Python argparse & sys.argv — CLI Arguments
When you run a script from the terminal, the words after the script name are command-line arguments. Python gives you two ways to read them: the raw sys.argvsys.argv list, and the full-featured argparseargparse library.
# $ python greet.py Ada --times 3
import sys
print(sys.argv) # ['greet.py', 'Ada', '--times', '3']# $ python greet.py Ada --times 3
import sys
print(sys.argv) # ['greet.py', 'Ada', '--times', '3']sys.argv — the raw list
sys.argvsys.argv is a list of strings. The first item is always the script name; the rest are the arguments, as strings.
import sys
# $ python add.py 3 4
if len(sys.argv) != 3:
print("Usage: python add.py NUM NUM")
sys.exit(1)
a = int(sys.argv[1]) # convert from string!
b = int(sys.argv[2])
print(a + b) # 7import sys
# $ python add.py 3 4
if len(sys.argv) != 3:
print("Usage: python add.py NUM NUM")
sys.exit(1)
a = int(sys.argv[1]) # convert from string!
b = int(sys.argv[2])
print(a + b) # 7sys.argvsys.argv is fine for one or two arguments, but it forces you to handle conversion, validation, defaults, and help text by hand. For anything real, use argparseargparse.
argparse — the proper way
argparseargparse parses arguments, converts types, generates --help--help, and reports errors automatically.
import argparse
parser = argparse.ArgumentParser(description="Greet someone.")
parser.add_argument("name", help="who to greet")
parser.add_argument("--times", type=int, default=1, help="how many times")
args = parser.parse_args() # reads from sys.argv
for _ in range(args.times):
print(f"Hello, {args.name}!")import argparse
parser = argparse.ArgumentParser(description="Greet someone.")
parser.add_argument("name", help="who to greet")
parser.add_argument("--times", type=int, default=1, help="how many times")
args = parser.parse_args() # reads from sys.argv
for _ in range(args.times):
print(f"Hello, {args.name}!")Running it:
$ python greet.py Ada --times 2
Hello, Ada!
Hello, Ada!
$ python greet.py --help
usage: greet.py [-h] [--times TIMES] name
...$ python greet.py Ada --times 2
Hello, Ada!
Hello, Ada!
$ python greet.py --help
usage: greet.py [-h] [--times TIMES] name
...Positional vs optional arguments
| Kind | Defined as | Example |
|---|---|---|
| Positional | add_argument("name")add_argument("name") | python app.py Adapython app.py Ada |
| Optional | add_argument("--times")add_argument("--times") | python app.py --times 3python app.py --times 3 |
| Flag | add_argument("--verbose", action="store_true")add_argument("--verbose", action="store_true") | python app.py --verbosepython app.py --verbose |
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("filename") # required positional
parser.add_argument("--limit", type=int, default=10) # optional with default
parser.add_argument("--verbose", action="store_true")# flag -> True/False
# parse_args can take an explicit list (handy for testing)
args = parser.parse_args(["data.txt", "--limit", "5", "--verbose"])
print(args.filename) # data.txt
print(args.limit) # 5
print(args.verbose) # Trueimport argparse
parser = argparse.ArgumentParser()
parser.add_argument("filename") # required positional
parser.add_argument("--limit", type=int, default=10) # optional with default
parser.add_argument("--verbose", action="store_true")# flag -> True/False
# parse_args can take an explicit list (handy for testing)
args = parser.parse_args(["data.txt", "--limit", "5", "--verbose"])
print(args.filename) # data.txt
print(args.limit) # 5
print(args.verbose) # TrueTip:
parse_args()parse_args()readssys.argvsys.argvby default, but you can pass a list —parse_args(["a", "b"])parse_args(["a", "b"])— which is perfect for tests and examples.
Useful add_argument options
| Option | Effect |
|---|---|
type=inttype=int | Convert the value (to int, float, etc.). |
default=...default=... | Value used when the argument is omitted. |
required=Truerequired=True | Make an optional argument mandatory. |
choices=[...]choices=[...] | Restrict to a fixed set of values. |
action="store_true"action="store_true" | Boolean flag (no value needed). |
nargs="+"nargs="+" | Accept multiple values into a list. |
help="..."help="..." | Text shown in --help--help. |
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--mode", choices=["fast", "safe"], default="safe")
parser.add_argument("--files", nargs="+") # one or more values
args = parser.parse_args(["--mode", "fast", "--files", "a.txt", "b.txt"])
print(args.mode) # fast
print(args.files) # ['a.txt', 'b.txt']import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--mode", choices=["fast", "safe"], default="safe")
parser.add_argument("--files", nargs="+") # one or more values
args = parser.parse_args(["--mode", "fast", "--files", "a.txt", "b.txt"])
print(args.mode) # fast
print(args.files) # ['a.txt', 'b.txt']Short flags
Add a one-letter alias alongside the long name:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-n", "--number", type=int, default=1)
args = parser.parse_args(["-n", "7"])
print(args.number) # 7import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-n", "--number", type=int, default=1)
args = parser.parse_args(["-n", "7"])
print(args.number) # 7Common pitfalls
sys.argvsys.argvvalues are strings — convert withint()int()/float()float().sys.argv[0]sys.argv[0]is the script name, not the first argument.- Dashes become underscores —
--max-size--max-sizeis read asargs.max_sizeargs.max_size. store_truestore_trueflags default toFalseFalse— presence flips them toTrueTrue.- argparse exits on bad input — it prints usage and calls
sys.exitsys.exit, which is usually what you want.
Practice Exercises
Exercise 1 – Read from a simulated argv
Exercise 2 – Parse a positional argument
Exercise 3 – An optional integer with a default
Summary
sys.argvsys.argvis the raw list of string arguments (argv[0]argv[0]is the script name).argparseargparseadds types, defaults, choices, flags, validation, and auto-generated--help--help.- Positional args are required;
--optional--optionalargs can have defaults;store_truestore_truemakes boolean flags. - Pass an explicit list to
parse_args([...])parse_args([...])for testing and examples.
If this helped you, consider buying me a coffee ☕
Buy me a coffeeWas this page helpful?
Let us know how we did
