【python基础】11-命令行参数

已知参数数目

#!/usr/bin/python3

import sys

if len(sys.argv) != 3:
    sys.exit("Error: Please provide exactly two numbers as arguments")
else:
    (num1, num2) = sys.argv[1:]
    total = int(num1) + int(num2)
    print("{} + {} = {}".format(num1, num2, total))
  • 传入Python程序的命令行参数自动保存在sys.argv列表中
  • 让用户知道错误信息是非常好的想法
  • 当程序因为错误的使用而终止报错,使用sys.exit()获取错误信息或者一个自定义状态码
  • Python文档 – sys模块
$ ./sum_of_two_numbers.py 2 3
2 + 3 = 5
$ echo $?
0

$ ./sum_of_two_numbers.py 2 3 7
Error: Please provide exactly two numbers as arguments
$ echo $?
1

$ ./sum_of_two_numbers.py 2 'x'
Traceback (most recent call last):
  File "./sum_of_two_numbers.py", line 9, in <module>
    total = int(num1) + int(num2)
ValueError: invalid literal for int() with base 10: 'x'
$ echo $?
1

变长参数

#!/usr/bin/python3

import sys, pathlib, subprocess

if len(sys.argv) < 2:
    sys.exit("Error: Please provide at least one filename as argument")

input_files = sys.argv[1:]
files_not_found = []

for filename in input_files:
    if not pathlib.Path(filename).is_file():
        files_not_found.append("File '{}' not found".format(filename))
        continue

    line_count = subprocess.getoutput('wc -l < ' + filename)
    print("{0:40}: {1:4} lines".format(filename, line_count))

print("\n".join(files_not_found))
$ ./varying_command_line_args.py
Error: Please provide at least one filename as argument
$ echo $?
1

$ #选择性呈现输出
$ ./varying_command_line_args.py *.py
calling_shell_commands.py               : 14   lines
for_loop.py                             : 6    lines
functions_default_arg_value.py          : 16   lines
functions.py                            : 24   lines
hello_world.py                          : 3    lines
if_elif_else.py                         : 22   lines
if_else_oneliner.py                     : 6    lines
shell_command_output_redirections.py    : 21   lines
...

$ ./varying_command_line_args.py hello_world.py xyz.py for_loop.py abc.py
hello_world.py                          : 3    lines
for_loop.py                             : 6    lines
File 'xyz.py' not found
File 'abc.py' not found
  • 如果你的Python版本不是3.4或者更高,使用os模块而不是pathlib模块进行文件检查
import os

if not os.path.isfile(filename):
    sys.exit("File '{}' not found".format(filename))

在代码中使用程序名

#!/usr/bin/python3

import sys, pathlib, subprocess, re

if len(sys.argv) != 2:
    sys.exit("Error: Please provide exactly one filename as argument")

program_name = sys.argv[0]
filename = sys.argv[1]

if not pathlib.Path(filename).is_file():
    sys.exit("File '{}' not found".format(filename))

if re.search(r'line_count.py', program_name):
    lc = subprocess.getoutput('wc -l < ' + filename)
    print("No. of lines in '{}' is: {}".format(filename, lc))
elif re.search(r'word_count.py', program_name):
    wc = subprocess.getoutput('wc -w < ' + filename)
    print("No. of words in '{}' is: {}".format(filename, wc))
else:
    sys.exit("Program name '{}' not recognized".format(program_name))
  • 基于程序名,同一程序可以用作不同的目的
$ ./line_count.py if_elif_else.py
No. of lines in 'if_elif_else.py' is: 22

$ ln -s line_count.py word_count.py
$ ./word_count.py if_elif_else.py
No. of words in 'if_elif_else.py' is: 73

$ ln -s line_count.py abc.py
$ ./abc.py if_elif_else.py
Program name './abc.py' not recognized

$ wc -lw if_elif_else.py
 22  73 if_elif_else.py

命令行开关

#!/usr/bin/python3

import argparse, subprocess

parser = argparse.ArgumentParser()
parser.add_argument('-f', '--file', help="file to be sorted", required=True)
parser.add_argument('-u', help="sort uniquely", action="store_true")
args = parser.parse_args()

if args.u:
    subprocess.call(['sort', '-u', args.file, '-o', args.file])
else:
    subprocess.call(['sort', args.file, '-o', args.file])
  • 使用argparse模块是一种更简单的方式使得构建的程序像shell命令
  • 默认它添加一个help选项-h(短格式)和--help选项(长格式)处理错误的使用

在这个例子中:

  • -f--file声明为必需选项,它接受一个参数(文件名)
  • -u是一个可选的标记
  • help用于指定展示的文本和选项的帮助信息
$ ./sort_file.py
usage: sort_file.py [-h] -f FILE [-u]
sort_file.py: error: the following arguments are required: -f/--file

$ ./sort_file.py -h
usage: sort_file.py [-h] -f FILE [-u]

optional arguments:
  -h, --help            show this help message and exit
  -f FILE, --file FILE  file to be sorted
  -u                    sort uniquely

$ ./sort_file.py -f test_list.txt
$ cat test_list.txt
async_test
basic_test
input_test
input_test
output_test
sync_test

$ ./sort_file.py -f test_list.txt -u
$ cat test_list.txt
async_test
basic_test
input_test
output_test
sync_test

$ ./sort_file.py -f xyz.txt
sort: cannot read: xyz.txt: No such file or directory
  • 指定位置参数
#!/usr/bin/python3

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('num1', type=int, help="first number")
parser.add_argument('num2', type=int, help="second number")
args = parser.parse_args()

total = args.num1 + args.num2
print("{} + {} = {}".format(args.num1, args.num2, total))
  • 比手动解析sys.argv更可读的方法,同时提供默认帮助和错误处理
  • 需要的类型转换可以在构建参数时指定
$ ./sum2nums_argparse.py
usage: sum2nums_argparse.py [-h] num1 num2
sum2nums_argparse.py: error: the following arguments are required: num1, num2

$ ./sum2nums_argparse.py -h
usage: sum2nums_argparse.py [-h] num1 num2

positional arguments:
  num1        first number
  num2        second number

optional arguments:
  -h, --help  show this help message and exit

$ ./sum2nums_argparse.py 3 4
3 + 4 = 7

$ ./sum2nums_argparse.py 3 4 7
usage: sum2nums_argparse.py [-h] num1 num2
sum2nums_argparse.py: error: unrecognized arguments: 7

进一步阅读

点赞