Best practices for program arguments
Only reference sys.argv
inside of the main block
The main block is a special if
statement:
if __name__ == "__main__":
# this is the main block
This main block is run whenever you use python program.py
, and it only runs
the main block located in program.py
.
Since this is the first block of code that is run when a program is run, it is
best practice to only reference sys.argv
inside of this block.
Bad example
First, let’s show a bad example of a program that references sys.argv
outside
of the main block:
import sys
def main():
# this accesses sys.argv outside of the main block
print(f"This prints sys.argv[1], {sys.argv[1]}, inside of the main function!")
if __name__ == "__main__":
print("This is the bad example!")
main()
Good example
Now, here’s a good example that only references sys.argv
inside of the main
block. We encourage you to model your code after this example.
import sys
def main(argument: str):
print(f"This prints the argument, {argument}, that was passed to the main function!")
if __name__ == "__main__":
print("This is the good example")
# This references sys.argv inside of the main block
main(sys.argv[1])
Running the program:
python good_example.py argument1
produces the following output:
This is the good_example!
This prints the argument, argument1, that was passed to the main function!
While the output of both the good and bad examples are nearly the same, keeping
all references to sys.argv
in the main block will make a critical difference
in the future as you learn about modularization and testing. Following the
better design now will help you avoid trouble later.
Passing the wrong number of arguments to your program
A common error that occurs when dealing with sys.argv
is an IndexError
. This
occurs when the user doesn’t provide enough arguments to the program and the
program tries to reference an argument that doesn’t exist.
Using the good example above, running the program:
python good_example.py
results in the following error message:
This is the good example
Traceback (most recent call last):
File "good_example.py", line 10, in <module>
main(sys.argv[1])
~~~~~~~~^^^
IndexError: list index out of range
Here, we see that the error occured on line 10 of good_example.py
. The tilde
~
and caret ^
symbols point to where the error occured. In this case, the
error occured when trying to reference sys.argv[1]
when using it as a
parameter for the main()
function.
Finally, the error message tells us that the error was an IndexError
. This
means that we tried to access an index of a list that doesn’t exist. In this
case, sys.argv
only has one item at sys.argv[0]
, which is the name of the
program, "good_example.py"
. As a result, the program throws an error when it
tries to access sys.argv[1]
.
Check the length of sys.argv
before using it
It is common for a program to check the number of arguments before trying to
access them. If the user doesn’t provide enough arguments, the program can print
a helpful message to help the user understand which arguments they need to
provide. This is easier for the user to understand than an IndexError
message.
For example, you could write code like this:
import sys
def main(argument: str):
print(f"This prints the argument, {argument}, that was passed to the main function!")
if __name__ == "__main__":
if len(sys.argv) != 2:
print("You didn't provide the correct number of arguments!")
print("Call this program with like this:")
print("python good_example.py argument1")
exit()
main(sys.argv[1])
In this class, the tests we give you will always provide the correct number of
arguments to your programs, so you don’t need to worry about checking the length
of sys.argv
in your code.