python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > python解析命令行参数

python中解析命令行参数的示例详解

作者:仙草哥哥

这篇文章主要为大家详细介绍了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解析命令行参数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文