python中解析命令行参数的示例详解
作者:仙草哥哥
命令行参数
加密程序
考虑这样一个加密程序,其中一个功能,是对一段字符串进行base64加密,另一个功能,是对一段base64字符串解密:
import base64 def encrypt_to_base64(input_string): byte_data = input_string.encode("utf-8") base64_encoded = base64.b64encode(byte_data) return base64_encoded.decode("utf-8") def decrypt_from_base64(base64_string): byte_data = base64_string.encode("utf-8") decoded_data = base64.b64decode(byte_data) return decoded_data.decode("utf-8") encrypt_to_base64("sagegrass") decrypt_from_base64("c2FnZWdyYXNz")
对于这样一个功能,如果我希望通过命令行调用,然后快速得到结果,可能是像这样的:
# 设置-e选项,进行加密 python base64_encrypt.py -e "sagegrass" # 设置-d选项,进行解密 python base64_encrypt.py -d "c2FnZWdyYXNz"
那么,该怎么做到呢?
sys.argv
命令行参数以列表的形式,保存于sys模块的argv属性中,具体来说
import sys print(sys.argv) # 对于python base64_encrypt.py -e "123456",结果为:['base64_encrypt.py', '-e', 'sagegrass'] # 对于python base64_encrypt.py -d "MTIzNDU2",结果为:['base64_encrypt.py', '-d', 'c2FnZWdyYXNz']
处理命令行参数
因此,根据sys.argv的返回结果,我们可以假设,如果用户的使用方法正确,那么,我们可以:
import base64 import sys def encrypt_to_base64(input_string): byte_data = input_string.encode("utf-8") base64_encoded = base64.b64encode(byte_data) return base64_encoded.decode("utf-8") def decrypt_from_base64(base64_string): byte_data = base64_string.encode("utf-8") decoded_data = base64.b64decode(byte_data) return decoded_data.decode("utf-8") if len(sys.argv) >= 3: if sys.argv[1] == "-e": print(encrypt_to_base64(sys.argv[2])) elif sys.argv[1] == "-d": print(decrypt_from_base64(sys.argv[2]))
此时,我们程序已经可以正确处理-e以及-d的参数了。
复杂命令行参数
计算器案例
考虑这样一个计算器程序,允许接受两个参数,并且选择一个操作,进行加,减,乘,除的操作。
但是,也可以允许只接受一个参数,并且选择进行平方,或者开根号的操作。
同时,也应该允许用户可以先提供数字,或者后提供数字。
# 实现一个加法操作 python calculator.py 520 0.1314 --operation add python calculator.py -o add 520 0.1314 # 实现一个平方操作 python calculator.py -o square 5
因为操作较为复杂,用户可能搞不清楚,所以同样应该提供一份帮助说明。
python calculator.py -h
那么,在这种情况下,如果还是使用sys.argv,并且在整个列表中,去解析命令行参数,会非常麻烦。因此,需要更好的工具,去处理这个问题。
argparse
argparse是一个更好的工具,可以处理更加复杂的命令行参数。
创建ArgumentParser对象
parser = argparse.ArgumentParser(description="base64加解密")
添加位置参数
parser.add_argument("text", type=str, help="用于加解密的一段文本")
添加操作符
parser.add_argument("-e", "--encrypt", action="store_true", help="对文本进行base64加密") parser.add_argument("-d", "--decrypt", action="store_true", help="对文本进行base64解密")
解析参数
args = parser.parse_args() if args.encrypt: print(encrypt_to_base64(args.text)) elif args.decrypt: print(decrypt_from_base64(args.text)) argparse处理base64加解密 import base64 import argparse def encrypt_to_base64(input_string): byte_data = input_string.encode("utf-8") base64_encoded = base64.b64encode(byte_data) return base64_encoded.decode("utf-8") def decrypt_from_base64(base64_string): byte_data = base64_string.encode("utf-8") decoded_data = base64.b64decode(byte_data) return decoded_data.decode("utf-8") parser = argparse.ArgumentParser(description="base64加解密") parser.add_argument("text", type=str, help="待加解密的文本") parser.add_argument("-e", "--encrypt", action="store_true", help="对文本进行base64加密") parser.add_argument("-d", "--decrypt", action="store_true", help="对文本进行base64解密") args = parser.parse_args() if args.encrypt: print(encrypt_to_base64(args.text)) elif args.decrypt: print(decrypt_from_base64(args.text))
argparse处理计算器
import argparse import math parser = argparse.ArgumentParser(description="一个命令行的计算器") parser.add_argument("num1", type=float, help="第一个数字") parser.add_argument("num2", type=float, nargs='?', default=None, help="第二个数字(平方和开根号操作无需提供)") parser.add_argument("-o", "--operation", choices=["add", "sub", "mul", "div", "square", "sqrt"], default="add", help="选择操作:add(加),sub(减),mul(乘),div(除),square(平方),sqrt(开根号)") args = parser.parse_args() if args.operation in ["add", "sub", "mul", "div"]: if args.num2 is None: parser.error(f"操作'{args.operation}'需要提供两个数字。") elif args.operation in ["square", "sqrt"]: if args.num2 is not None: parser.error(f"操作'{args.operation}'只需要提供一个数字。") if args.operation == "add": result = args.num1 + args.num2 elif args.operation == "sub": result = args.num1 - args.num2 elif args.operation == "mul": result = args.num1 * args.num2 elif args.operation == "div": if args.num2 == 0: result = "除数不能为零!" else: result = args.num1 / args.num2 elif args.operation == "square": result = args.num1 ** 2 elif args.operation == "sqrt": if args.num1 < 0: result = "不能对负数开平方根!" else: result = math.sqrt(args.num1) else: result = None if result is not None: print(f"结果: {result}")
在这种情况下,使用-h查看帮助的时候,就会发现,已经自动生成了一份简洁的帮助信息。
安装为全局命令
全局命令
我们可能经常观察到这样一种情况,在使用他人的第三方库的时候,可以使用命令,例如,lunar-find 春节 2025
而对比我们的命令行程序,则必须要按照python xxx的形式使用,而且必须找到对应的py文件,这并不方便,那么该可以让我们也使用全局命令呢?
my-lunar-find
因为原本的lunar-find输出格式不够灵活,因此,我们对其进行简单的重写,以满足可以输出任意格式的时间。
关于原本的lunar-find工具,如果你并不了解,可以看看这篇文章,lunarcalendar的使用
import argparse from lunarcalendar.festival import festivals from lunarcalendar.solarterm import solarterms from itertools import chain from datetime import date def main(): parser = argparse.ArgumentParser(description="自行创建的lunar-find,修改了原本的日期格式") parser.add_argument("fs_or_st", type=str, help="需要查找的节日或节气") parser.add_argument("year", type=int, help="年份") parser.add_argument("-f", "--format", default="%Y年%m月%d日", help="按照需要的格式重新格式化,%Y为年,%m为月,%d为日") args = parser.parse_args() for day in chain(festivals, solarterms): if day.get_lang("zh") == args.fs_or_st: formatted_time = day(args.year).strftime(args.format) print(formatted_time) if __name__ == "__main__": main()
此时,可以通过提供--format,来按照需要格式化时间。
python my_lunar_find.py 春节 2025 # 输出:2025年01月29日
python my_lunar_find.py 春节 2025 --format %Y/%m/%d # 输出:2025/01/29
python my_lunar_find.py 春节 2025 --format %Y-%m-%d # 输出:2025-01-29
安装
编写一份setup.py
from setuptools import setup setup( name="my_lunar_find", version="1.0", py_modules=["my_lunar_find"], entry_points={ "console_scripts": [ "my-lunar-find = my_lunar_find:main", ], }, )
安装:pip install .
注意:其中的.代表当前路径,因此需要在包含setup.py的目录下运行。
此时,是安装了一个我们自己的模块,my-lunar-find==1.0
调用命令:my-lunar-find 春节 2025
到此这篇关于python中解析命令行参数的示例详解的文章就介绍到这了,更多相关python解析命令行参数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!